Cognitoの自己サインアップと未認証アクセスを確かめる手順【2026年版】
Amazon Cognito でログイン機能を作ったとき、「新規登録」をだれでもできる設定のままにしていませんか。それだけなら普通の会員制アプリですが、ID プールにつないで AWS の一時認証情報を配っていると、話が変わります。
2026年11月、AI で動く攻撃ツールが自己サインアップが有効なユーザープールに登録し、ID プールから AWS の一時認証情報を得た事例が紹介され、技術者の間で話題になりました。この記事では、自分の Cognito が同じ形になっていないかをコンソールと AWS CLI で確かめる手順と、危ないときの直し方をまとめます。

設定を「有効か無効か」だけでなく、ロールの権限まで含めて点検する——そのためのチェックリストという位置づけです。
この記事はこんな人向けです
- Amazon Cognito でログイン機能を作ったが、「だれでも登録できる」設定のままか分からない
- ID プールの「ゲストアクセス」や IAM ロールの権限を、コンソールと AWS CLI で点検したい
- 危ない設定だったときに、アプリを壊さずに直す順番と注意点を知りたい
Cognitoの自己サインアップと未認証アクセスとは?一言でまとめると
自己サインアップは「アプリの利用者が自分でアカウントを作れる機能」、未認証アクセスは「ログインしていない人にも AWS の認証情報を渡す機能」です。どちらも便利ですが、組み合わせ方しだいで「だれでも AWS を触れる入口」になります。
Cognito には役割の違う2つの部品があります。
| 部品 | 役割 | この記事で見る設定 |
|---|---|---|
| ユーザープール | ユーザーの登録・サインインを受け持ち、ID トークンなどを発行する | 自己サインアップ(AllowAdminCreateUserOnly)、属性の書き込み権限 |
| ID プール | トークンと引き換えに、IAM ロールの一時認証情報を渡す | ゲストアクセス(AllowUnauthenticatedIdentities)、認証済み/ゲスト用のロール |
| IAM ロール | 一時認証情報で何ができるかを決める | 信頼ポリシーの条件(aud・amr)、付けている権限 |

ポイントは、アプリクライアント ID は秘密ではないことです。AWS の開発者ガイドも、登録を受け付けるユーザープールは「公開されていて見つけられるアプリクライアント ID を知る、インターネット上のだれにでも」ユーザーを作ると書いています。ブラウザやスマホで動くアプリは、サインインのためにアプリの中にクライアント ID を持つのが普通なので、「ID を知られていないから大丈夫」とは考えないほうが安全です。
なぜ今確かめたいのか:話題になった事例
きっかけは、クラスメソッドの技術ブログ DevelopersIO が2026年11月14日に公開した記事です。セキュリティ企業 Datadog の研究チーム Datadog Security Labs が11月9日に報告した、AI エージェントが自分で計画して動く攻撃ツール「ARTEX」の事例を紹介しています。
Datadog Security Labs の報告では、ARTEX は公開されたユーザープールに登録し、ID プールを通じて短期の認証情報を手に入れました。ただし、その後に試した読み取りの操作は、認証済みロールに権限が無かったためすべて失敗しています。登録時には pre sign-up Lambda の検証に何度も弾かれていた、とも書かれています。
この事例から言えることは2つあると IT Picks は考えています。
- 自己サインアップが有効なら、「認証済み」は「本人確認済み」という意味ではない。だれでも登録できる以上、認証済みロールは実質だれでも使えるロールになる
- 最後の防波堤はロールの権限。権限を絞っていた環境では、認証情報を取られても被害が出なかった

この記事では攻撃の手順には触れません。自分の設定を確かめて閉じることだけに絞ります。
危ない組み合わせはどれ?設定ごとのリスク
「自己サインアップが有効=すぐ危ない」ではありません。一般の人が会員登録するアプリなら、自己サインアップは必要な機能です。大事なのはどの設定と組み合わさっているかです。
| 設定の組み合わせ | だれが何を得られるか | リスク | まずやること |
|---|---|---|---|
| 自己サインアップ:無効、ゲストアクセス:無効 | 管理者が作ったユーザーだけ | 低い | ロールの権限を年1回は見直す |
| 自己サインアップ:有効、ID プールにつないでいない | だれでも登録してアプリのトークンを得られる | 中 | アプリの API の認可を確かめる |
| 自己サインアップ:有効、ID プールにつないでいる | だれでも登録して認証済みロールの一時認証情報を得られる | 高い | 登録を止めるか、認証済みロールを最小権限に |
| ゲストアクセス:有効 | 登録もせずにゲスト用ロールの一時認証情報を得られる | 高い | 使っていなければ無効に。使うなら最小権限に |
| 基本(クラシック)フロー:有効 | トークンを、ID プールを信頼する別のロールと交換できる | 高い | 使っていなければ無効に |
| 属性の書き込み権限が既定のまま | 利用者が自分の属性(カスタム属性を含む)を書き換えられる | 属性を認可に使っていれば高い | 認可に使う属性を書き込み不可に |

見落としやすいのがゲスト用ロールの範囲です。ID プールの「強化フロー」では、ゲストの認証情報に AWS が自動で範囲を絞るポリシーを重ねます。ただし、その範囲には S3・DynamoDB・Lambda などよく使うサービスが含まれるため、ゲスト用ロールに s3:* を付けていれば、ゲストでも S3 を広く触れてしまいます。自動の絞り込みに頼らず、ロールそのものを絞るのが基本です。
確認の手順①:コンソールで見る場所
まずはマネジメントコンソールで、画面の場所を押さえます。読むだけなら設定は何も変わりません。
① ユーザープールの自己サインアップ
- Amazon Cognito のコンソールで User pools を開き、対象のユーザープールを選ぶ
- 左の Sign-up メニューを開く
- Self-service sign-up の欄で、Enable self-registration が有効かを見る
有効なら、アプリクライアント ID を知るだれでも登録できる状態です。

② アプリクライアントの属性の書き込み権限
- 同じユーザープールの App clients メニューで、アプリクライアントを1つずつ開く
- Attribute permissions タブで、書き込みできる属性を見る
custom:role や custom:tenant のように権限の判断に使っている属性が書き込み可能になっていないかを見ます。AWS のガイドは、そうした属性をすべてのアプリクライアントの書き込み権限から外すよう求めています。属性はアプリクライアントの間で共有されるので、1つでも書けるクライアントがあれば意味がありません。
③ ID プールのゲストアクセスとロール
- コンソールの Identity pools で対象の ID プールを選ぶ
- User access タブを開く
- Guest access の Status が Active か Inactive かを見る
- Authenticated access と Guest access に割り当てられた IAM ロール名を控える
- ID プールの設定で、Basic (classic) authentication が有効になっていないかも見る

④ IAM ロールの信頼ポリシーと権限
IAM コンソールで、③で控えたロールを開きます。Trust relationships タブで信頼ポリシーの条件を、Permissions タブで付いている権限を見ます。見るべき点は次の手順②の表と同じです。
確認の手順②:AWS CLIでまとめて確かめる
ユーザープールや ID プールが多いと、画面で1つずつ見るのは大変です。AWS CLI なら、読み取りの API だけで同じことを確かめられます。リージョンごとに分かれているので、使っているリージョンをすべて回ります。
| 確かめること | コマンド | 危ない値 |
|---|---|---|
| ユーザープールの一覧 | aws cognito-idp list-user-pools |
— |
| 自己サインアップ | aws cognito-idp describe-user-pool |
AllowAdminCreateUserOnly が false |
| アプリクライアントの一覧 | aws cognito-idp list-user-pool-clients |
— |
| 属性の書き込み権限 | aws cognito-idp describe-user-pool-client |
WriteAttributes が表示されない(=既定で全部書ける)か、認可用の属性を含む |
| ID プールの一覧 | aws cognito-identity list-identity-pools |
— |
| ゲストアクセス・基本フロー | aws cognito-identity describe-identity-pool |
AllowUnauthenticatedIdentities / AllowClassicFlow が true |
| 割り当てたロール | aws cognito-identity get-identity-pool-roles |
unauthenticated のロールがある |
| 信頼ポリシーの条件 | aws iam get-role |
aud が無い、amr で絞っていない |
| 付けている権限 | aws iam list-attached-role-policies / list-role-policies / get-role-policy |
* の操作や * のリソース |
① ユーザープールを確かめる
ターミナル(AWS CLI)
aws cognito-idp list-user-pools --max-results 60 --query 'UserPools[].{Id:Id,Name:Name}'
aws cognito-idp describe-user-pool --user-pool-id <ユーザープールID> \
--query 'UserPool.{AdminCreateUserConfig:AdminCreateUserConfig,LambdaConfig:LambdaConfig}'
AllowAdminCreateUserOnly が true なら自己サインアップは無効、false なら有効です。LambdaConfig に PreSignUp があれば、登録時に独自の検証を入れています。
② アプリクライアントを確かめる
ターミナル(AWS CLI)
aws cognito-idp list-user-pool-clients --user-pool-id <ユーザープールID> \
--query 'UserPoolClients[].{Name:ClientName,Id:ClientId}'
aws cognito-idp describe-user-pool-client --user-pool-id <ユーザープールID> --client-id <クライアントID> \
--query 'UserPoolClient.{WriteAttributes:WriteAttributes,HasSecret:ClientSecret!=null}'
WriteAttributes が null(表示されない)なら、書き込み権限を一度も絞っていない既定の状態です。既定以外を設定したときだけ値が返るためです。既定で書ける範囲は、AWS の開発者ガイドでは「標準属性とカスタム属性のすべて」、API リファレンスでは「標準属性」と書き方が分かれています。どちらにしても、認可に使う属性があるなら WriteAttributes を明示して外すのが確実です。
③ ID プールとロールを確かめる
ターミナル(AWS CLI)
aws cognito-identity list-identity-pools --max-results 60
aws cognito-identity describe-identity-pool --identity-pool-id <IDプールID> \
--query '{Guest:AllowUnauthenticatedIdentities,Classic:AllowClassicFlow,Providers:CognitoIdentityProviders[].ProviderName}'
aws cognito-identity get-identity-pool-roles --identity-pool-id <IDプールID>
ターミナル(AWS CLI)
aws iam get-role --role-name <ロール名> --query 'Role.AssumeRolePolicyDocument'
aws iam list-attached-role-policies --role-name <ロール名>
aws iam list-role-policies --role-name <ロール名>
aws iam get-role-policy --role-name <ロール名> --policy-name <インラインポリシー名>
Providers にユーザープールが入っていて、そのユーザープールの自己サインアップが有効なら、表の「高い」の組み合わせです。本番のユーザープールに試しに登録して確かめる必要はありません。上の読み取りの値だけで判断できます。
判定:自分の環境は直すべき?
確認した値を、次のチャートに当てはめます。

判断に迷いやすいのは、一般の人が登録するアプリで、ID プールも使っているケースです。この場合は自己サインアップを止められないので、「だれでも認証済みロールを使える」前提で権限を設計し直すのが答えになります。たとえば S3 なら、${cognito-identity.amazonaws.com:sub} を使って自分の ID のフォルダだけに絞る形が、AWS のガイドに例として載っています。
危ないときの直し方
直し方は次の5段階です。本番で変える前に、開発用の環境で試すのが安全です。

| 直すこと | コンソール | AWS CLI | 注意点 |
|---|---|---|---|
| 自己サインアップを止める | Sign-up → Self-service sign-up → Enable self-registration を外す | update-user-pool --admin-create-user-config AllowAdminCreateUserOnly=true |
CLI は渡さなかった設定が既定値に戻る |
| ゲストアクセスを止める | Identity pools → User access → Guest access → Deactivate | update-identity-pool --no-allow-unauthenticated-identities |
CLI は名前・プロバイダーなども全部渡す |
| ゲスト用ロールを外す | User access でゲストのロールを外す | set-identity-pool-roles で authenticated だけ渡す |
ゲストアクセスを止めたあとに |
| 基本フローを止める | Basic (classic) authentication を無効に | update-identity-pool --no-allow-classic-flow |
アプリが基本フローを使っていないか先に確かめる |
| 信頼ポリシーを絞る | IAM → ロール → Trust relationships | aws iam update-assume-role-policy |
aud と amr の両方の条件を入れる |
| 権限を最小にする | IAM → ロール → Permissions | put-role-policy / detach-role-policy |
* をやめ、操作とリソースを具体的に |
| 属性を書き込み不可に | App clients → Attribute permissions | update-user-pool-client --write-attributes … |
すべてのクライアントで外す。CLI は他の設定も一緒に渡す |
① CLIで変えるときは「全部渡す」
いちばんつまずきやすいのが、update-user-pool・update-identity-pool・update-user-pool-client は、渡さなかった項目を既定値に戻す点です。AWS の API リファレンスにもはっきり書かれています。自己サインアップだけを止めたつもりが、メールの自動確認や Lambda トリガーまで消える、ということが起こります。
本番ではコンソールで変えるのがいちばん安全です。CLI で変えるなら、ID プールは次のように今の設定を JSON で取り出し、1か所だけ変えて渡す方法が確実です。
ターミナル(AWS CLI)
aws cognito-identity describe-identity-pool --identity-pool-id <IDプールID> > idpool.json
jq '.AllowUnauthenticatedIdentities=false' idpool.json > idpool-new.json
aws cognito-identity update-identity-pool --cli-input-json file://idpool-new.json
ユーザープールは describe の結果に更新できない項目も入っているため、そのままでは渡せません。describe の結果を保存し、Lambda トリガー・自動確認する属性・MFA など、使っている設定を一緒に指定するようにします。
② 信頼ポリシーに aud と amr を入れる
ID プールのロールの信頼ポリシーは、どの ID プールから(aud)、認証済みかゲストか(amr)の2つで絞ります。AWS のガイドにあるゲスト用ロールの形は次のとおりです。
信頼ポリシー(ゲスト用ロール)
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Federated": "cognito-identity.amazonaws.com" },
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": { "cognito-identity.amazonaws.com:aud": "<IDプールID>" },
"ForAnyValue:StringLike": { "cognito-identity.amazonaws.com:amr": "unauthenticated" }
}
}]
}
認証済みロールは amr の値を authenticated にします。今の IAM は aud の条件が無い信頼ポリシーを保存できませんが、それ以前に作ったロールは条件なしのまま残っていることがあります。古い環境ほど一度見ておく価値があります。
③ 権限は「その画面で本当に使う操作」だけ
認証済み・ゲストどちらのロールも、アプリが実際に呼ぶ API と、そのリソースだけに絞ります。AWS のガイドには、S3 の1つのファイルだけを読む、自分の ID のフォルダだけを読み書きする、DynamoDB で自分の ID の行だけを扱う——といった例が載っています。s3:* や "Resource": "*" が出てきたら見直しの合図です。
実際にセットアップしてみた
2026年11月15日に、テスト用の Linux 環境で、AWS 公式のローカルエミュレーター「AWS Emulator」を使って、ここまでの確認と直し方を実際に動かしました。本物の AWS アカウントは使っていません。エミュレーターは AWS の API を手元で再現するツールで、アカウントなしで動きます。

① AWS Emulator と AWS CLI を入れる
公式の手順どおり、Debian パッケージを署名つきでダウンロードし、署名を確かめてから入れました。
ターミナル(テスト用の Linux 環境)
curl -fsSLo aws-emulator.deb https://downloads.aws.com/aws-emulator/packages/aws-emulator/LTS/latest/aws-emulator_amd64.deb
curl -fsSLO https://downloads.aws.com/aws-emulator/packages/aws-emulator/LTS/latest/aws-emulator_amd64.deb.sig
curl -fsSLo aws-publishing.asc https://downloads.aws.com/keys/gpg/current.asc
gpg --import aws-publishing.asc
gpg --verify aws-emulator_amd64.deb.sig aws-emulator.deb
sudo apt-get install -y ./aws-emulator.deb
aws-emulator -v
実行結果
gpg: Good signature from "SSM Publishing <ssm-publishing@amazon.com>" [unknown]
Version: 1.0.385
Release date: 2026.11.14
指紋は公式ドキュメントの値(98BC F336 … D940 F624)と同じでした。AWS CLI は公式のインストーラーで v2.40.3 を入れています。aws-emulator --telemetry off で起動すると、~/.aws/emulator/9297/ に専用の設定ファイルと認証情報が書き出されるので、環境変数で CLI の向き先を切り替えます。
ターミナル(テスト用の Linux 環境)
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN AWS_PROFILE
export AWS_ENDPOINT_URL=https://127.0.0.1:9297
export AWS_CONFIG_FILE=$HOME/.aws/emulator/9297/config
export AWS_SHARED_CREDENTIALS_FILE=$HOME/.aws/emulator/9297/emulator_credentials
export AWS_CA_BUNDLE=$HOME/.aws/emulator/9297/ca.pem
export AWS_REGION=us-west-2
本物の認証情報の環境変数を外しておくのが大事です。AWS_ENDPOINT_URL を忘れると、コマンドが本物の AWS に飛んでしまいます。
② わざと危ない設定を作り、確認コマンドを流す
自己サインアップ有効のユーザープール、ゲストアクセス有効の ID プール、s3:* を付けたゲスト用ロールを作り、上で紹介した確認コマンドを流しました。

AllowAdminCreateUserOnly は false、AllowUnauthenticatedIdentities は true と表示され、署名なし(--no-sign-request)の登録がそのまま通り、ユーザーは UNCONFIRMED で作られました。ゲストの ID も、ログインなしで払い出されています。確認コマンドの値と、実際に起きることが一致しているのが分かります。
③ 直して、もう一度流す
次に自己サインアップとゲストアクセスを止めました。ここで、update-user-pool で自己サインアップだけを渡したら、メールの自動確認(AutoVerifiedAttributes)が null に戻りました。API リファレンスの「渡さなかった項目は既定値に戻る」どおりの動きです。--auto-verified-attributes email を一緒に渡し直すと元に戻りました。

直したあとは、登録が NotAuthorizedException(SignUp is not permitted for this user pool)、ゲストの ID の払い出しも NotAuthorizedException(Unauthenticated access is not supported for this identity pool.)で断られました。update-identity-pool でも、プロバイダーを渡さずに実行すると、ユーザープールとのつながりが消えました。JSON で今の設定をまとめて渡す方法なら、プロバイダーを残したままゲストアクセスだけを止められました。
④ エミュレーターでは確かめられないこと
AWS Emulator は IAM ポリシーを本物の AWS と同じようには評価しません。実際に、aud の条件が無い信頼ポリシーもエラーにならず作れました(本物の IAM はエラーを返すと AWS のガイドにあります)。ロールの権限が正しく効いているかは、エミュレーターではなく、開発用の AWS アカウントで確かめる必要があります。開発用のアカウントを無料枠で用意するなら、AWS・GCP・Azure・OCI のクラウド無料枠の比較も参考になります。
直したあとも続けたいこと
一度直しても、新しいユーザープールや ID プールを作るたびに同じ問題は起こり得ます。仕組みで見張るのがおすすめです。
- Security Hub CSPM のコントロール [Cognito.2]: ID プールでゲストアクセスが有効だと「失敗」になります(重要度 Medium、AWS Config ルール
cognito-identity-pool-unauth-access-check) - CloudTrail で登録の急増を見る: DevelopersIO の記事は、CloudTrail で
SignUpの急な増加や、ID プール経由のセッションでのアクセス拒否の多発を見張るよう勧めています - pre sign-up Lambda で登録を絞る: 社内向けなど登録できる人が決まっているなら、メールのドメインなどで登録を断る仕組みを入れられます

最後に、点検に使えるチェックリストです。
| # | チェック項目 | 見る場所 | OK の状態 |
|---|---|---|---|
| 1 | 自己サインアップは必要か | Sign-up / describe-user-pool |
不要なら AllowAdminCreateUserOnly: true |
| 2 | 認可に使う属性を利用者が書けないか | App clients / describe-user-pool-client |
すべてのクライアントの WriteAttributes から外れている |
| 3 | ゲストアクセスは必要か | User access / describe-identity-pool |
不要なら AllowUnauthenticatedIdentities: false |
| 4 | 基本フローは止めているか | ID プールの設定 / describe-identity-pool |
AllowClassicFlow が true でない |
| 5 | 信頼ポリシーに条件があるか | IAM / get-role |
aud と amr の両方がある |
| 6 | 権限は最小か | IAM / get-role-policy など |
* の操作・* のリソースが無い |
| 7 | 見張りはあるか | Security Hub・CloudTrail | Cognito.2 が有効、登録の急増に気づける |
AWS のアカウントそのものを守る基本は、S3 やドメインの設定ミスを扱った記事でも紹介しています。

よくある質問
Q. 自己サインアップを無効にすると、今いるユーザーはどうなりますか?
A. 無効にすると、利用者が自分で登録する SignUp が NotAuthorizedException で断られ、マネージドログインの「Sign up」リンクも消えます。新しいユーザーは、管理者がコンソールか AdminCreateUser で作る形になります。登録画面を持つアプリなら、画面側の案内も合わせて変えておきましょう。
Q. アプリクライアントにシークレットを付ければ安全ですか? A. シークレット付きのクライアントは、シークレットを知らない人の登録を防げます。ただしシークレットはサーバー側で使うもので、ブラウザやスマホアプリに入れて配ってはいけないとされています。公開されるアプリでは解決策になりません。
Q. ゲストアクセスを使う機能があります。止められない場合は? A. ゲスト用ロールを、その機能が使う操作とリソースだけに絞ります。AWS の Security Hub の説明も、必要な場合は権限を慎重に絞り、使われ方を定期的に見直すよう求めています。
Q. 登録したユーザーは確認前(UNCONFIRMED)でもトークンをもらえますか? A. AWS のガイドでは、自分で登録したユーザーは確認が済むまでサインインできません。ただし pre sign-up Lambda で自動確認している場合は、確認コードなしでサインインできます。自動確認を使っているなら、その分だけ登録の入口が広いと考えてください。
まとめ
Cognito の自己サインアップと未認証アクセスを確かめる手順のポイントをまとめます。
- 自己サインアップ:
AllowAdminCreateUserOnlyが false なら、アプリクライアント ID を知るだれでも登録できる - 危ない組み合わせ:自己サインアップ有効+ID プール、またはゲストアクセス有効
- 確かめ方:コンソールの Sign-up・App clients・User access、CLI の
describe-user-pool・describe-identity-pool・get-identity-pool-roles・get-role - 直し方:登録とゲストアクセスを止め、信頼ポリシーに
audとamr、権限は最小に - つまずく所:
update-user-pool・update-identity-poolは渡さなかった設定を既定値に戻す - 続けること:Security Hub の Cognito.2、CloudTrail での登録の急増の見張り
まずは、使っているリージョンで上の確認コマンドを1回流してみるところから始めてみてください。
