結論
管理者向け API でしか読み取れないユーザー属性っぽいです。
クライアント向け API では読み書きできません。管理者向け API でも書き込みはできません。
2020/08/19 追記
いつの間にか API Reference に以下の記載が追加されていました。
SchemaAttributeType - Amazon Cognito Identity Provider
https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_SchemaAttributeType.html
We recommend that you use WriteAttributes in the user pool client to control how attributes can be mutated for new use cases instead of using DeveloperOnlyAttribute.
アプリクライアント毎に設定できる WriteAttibutes を使うことを推奨しているようです。
追記おわり
どういう事?
CloudFormation の Cognito User Pool リファレンスを眺めていた所、個人的に見慣れないオプションを発見しました。
Amazon Cognito UserPool SchemaAttribute - AWS CloudFormation
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-cognito-userpool-schemaattribute.html
DeveloperOnlyAttribute
属性タイプが開発者のみであるかを指定します。
Type: Boolean
Required: No
開発者のみとは?
気になるので Cognito 側の API リファレンスを確認してみます。
SchemaAttributeType - Amazon Cognito Identity Provider
https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_SchemaAttributeType.html
DeveloperOnlyAttribute
Specifies whether the attribute type is developer only.
Type: Boolean
Required: No
属性タイプが developer only か指定する的な。
この文脈で言う developer とは一体・・・
DeveloperOnlyAttribute を有効化した User Pool を作ってみる
DeveloperOnlyAttribute を有効化した myattribute
というカスタム属性を定義して User Pool を作ってみます。
勉強も兼ねて CloudFormation 使っていきます。
Resources:
DeveloperOnlyAttributeEnabledCognitoUserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: DeveloperOnlyAttributeEnabledCognitoUserPool
Schema:
- Name: myattribute
AttributeDataType: String
DeveloperOnlyAttribute: True
CloudFormation テンプレートを作成したら、 AWS CLI からデプロイ
$ aws cloudformation deploy --template-file ./myuserpool.yaml --stack-name developer-only-attribute-enabled-cognito-user-pool
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - developer-only-attribute-enabled-cognito-user-pool
出来上がった User Pool の設定を確認してみます。
$ aws cognito-idp describe-user-pool --user-pool-id ap-northeast-1_xxx
{
"UserPool": {
"Id": "ap-northeast-1_xxx",
"Name": "DeveloperOnlyAttributeEnabledCognitoUserPool",
"Policies": {
"PasswordPolicy": {
"MinimumLength": 8,
"RequireUppercase": true,
"RequireLowercase": true,
"RequireNumbers": true,
"RequireSymbols": true,
"TemporaryPasswordValidityDays": 7
}
},
"LambdaConfig": {},
"LastModifiedDate": 1565706803.41,
"CreationDate": 1565706803.41,
"SchemaAttributes": [
{
"Name": "sub",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": false,
"Required": true,
"StringAttributeConstraints": {
"MinLength": "1",
"MaxLength": "2048"
}
},
{
"Name": "name",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "given_name",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "family_name",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "middle_name",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "nickname",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "preferred_username",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "profile",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "picture",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "website",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "email",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "email_verified",
"AttributeDataType": "Boolean",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false
},
{
"Name": "gender",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "birthdate",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "10",
"MaxLength": "10"
}
},
{
"Name": "zoneinfo",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "locale",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "phone_number",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "phone_number_verified",
"AttributeDataType": "Boolean",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false
},
{
"Name": "address",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "updated_at",
"AttributeDataType": "Number",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"NumberAttributeConstraints": {
"MinValue": "0"
}
},
{
"Name": "dev:custom:myattribute",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": true,
"Mutable": false,
"Required": false,
"StringAttributeConstraints": {}
}
],
"VerificationMessageTemplate": {
"DefaultEmailOption": "CONFIRM_WITH_CODE"
},
"MfaConfiguration": "OFF",
"EstimatedNumberOfUsers": 0,
"EmailConfiguration": {
"EmailSendingAccount": "COGNITO_DEFAULT"
},
"UserPoolTags": {},
"AdminCreateUserConfig": {
"AllowAdminCreateUserOnly": false,
"UnusedAccountValidityDays": 7
},
"Arn": "arn:aws:cognito-idp:ap-northeast-1:123456789012:userpool/ap-northeast-1_xxx"
}
}
情報が盛り沢山ですが、今回着目するのは次の箇所です。
{
"Name": "dev:custom:myattribute",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": true,
"Mutable": false,
"Required": false,
"StringAttributeConstraints": {}
}
myattribute
というカスタム属性が作成されて、 DeveloperOnlyAttribute
が true
になってますね。
普通のカスタム属性は custom:attributename
のような形式ですが、 dev:custom:attributename
のように、 dev:
がプレフィックスとして追加されています。
ユーザーを作ってみる
まず、ユーザー作るのにアプリクライアントが必要なので作ります。
$ aws cognito-idp create-user-pool-client --user-pool-id ap-northeast-1_xxx --client-name myappclient --explicit-auth-flows "ADMIN_NO_SRP_AUTH"
{
"UserPoolClient": {
"UserPoolId": "ap-northeast-1_xxx",
"ClientName": "myappclient",
"ClientId": "6c0fdunb8s2ijns0ue2lfr8iia",
"LastModifiedDate": 1565707946.052,
"CreationDate": 1565707946.052,
"RefreshTokenValidity": 30,
"ExplicitAuthFlows": [
"ADMIN_NO_SRP_AUTH"
],
"AllowedOAuthFlowsUserPoolClient": false
}
}
これでユーザー作成の準備ができたので、カスタム属性を設定して sign up してみます。
$ aws cognito-idp sign-up --client-id 6c0fdunb8s2ijns0ue2lfr8iia --username sampleuser --password 'Passw@rd1234' --user-attributes Name=dev:custom:myattribute,Value=hogehoge
{
"UserConfirmed": false,
"UserSub": "bb64ae42-b532-4182-8efa-efc67662a345"
}
で、後で認証するため confirm しておきます。
$ aws cognito-idp admin-confirm-sign-up --user-pool-id ap-northeast-1_xxx --username sampleuser
admin-confirm-sign-up
コマンドは、成功時に特に出力は無いので admin-get-user
コマンドでユーザー状況を確認します。
$ aws cognito-idp admin-get-user --user-pool-id ap-northeast-1_xxx --username sampleuser
{
"Username": "sampleuser",
"UserAttributes": [
{
"Name": "sub",
"Value": "bb64ae42-b532-4182-8efa-efc67662a345"
},
{
"Name": "dev:custom:myattribute",
"Value": "hogehoge"
}
],
"UserCreateDate": 1565708213.268,
"UserLastModifiedDate": 1565708247.72,
"Enabled": true,
"UserStatus": "CONFIRMED"
}
UserStatus
が CONFIRMED
になってれば OK
認証して、カスタム属性を取得してみる
ADMIN_NO_SRP_AUTH
を使ってサクッと認証します。
$ aws cognito-idp admin-initiate-auth --user-pool-id ap-northeast-1_xxx --client-id 6c0fdunb8s2ijns0ue2lfr8iia --auth-flow ADMIN_NO_SRP_AUTH --auth-parameters USERNAME=sampleuser,PASSWORD=Passw@rd1234
{
"ChallengeParameters": {},
"AuthenticationResult": {
"AccessToken": "xxx",
"ExpiresIn": 3600,
"TokenType": "Bearer",
"RefreshToken": "yyy",
"IdToken": "zzz"
}
}
ここでレスポンスされる AccessToken
を使っていきます。
クライアント向け API でカスタム属性を読み書きしてみる
Cognito User Pool には、IAM のクレデンシャルを使って API 呼び出しを行う管理者向け API と、認証時に発行されるアクセストークンを使って API 呼び出しを行うクライアント向け API があります。
リソースのアクセス許可 - Amazon Cognito
https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/resource-permissions.html#amazon-cognito-signed-versus-unsigned-apis
署名された API と署名されていない API
AWS 認証情報で署名された API は、IAM ポリシーで制限することができます。次の Cognito API は署名されていないため、IAM ポリシーで制限することはできません。
署名されていない API を使って、カスタム属性の読み書きを試してみます。
$ aws cognito-idp get-user --access-token xxx
{
"Username": "sampleuser",
"UserAttributes": [
{
"Name": "sub",
"Value": "bb64ae42-b532-4182-8efa-efc67662a345"
}
]
}
UserAttributes
に dev:custom:myattribute
が含まれていません。
クライアント向け API で無理やり dev:custom:myattribute
を変更しようとしてみます。
$ aws cognito-idp update-user-attributes --user-attributes Name=dev:custom:myattribute,Value=fugafuga --access-token xxx
An error occurred (InvalidParameterException) when calling the UpdateUserAttributes operation: Invalid user attributes: custom:myattribute: Attribute cannot be updated.
ズバリなエラーメッセージですね。
カスタム属性として custom:myattribute
は存在しているようですが、更新はできないようです。
削除も試してみます。
$ aws cognito-idp delete-user-attributes --user-attribute-names dev:custom:myattribute --access-token xxx
An error occurred (InvalidParameterException) when calling the DeleteUserAttributes operation: Invalid user attributes: user.dev:custom:myattribute: Attribute cannot be updated.
user.dev:custom:myattribute
属性は存在するようですが、削除も含めた更新ができないようです。
管理者向け API でカスタム属性を読み書きしてみる
AWS 認証情報での署名が必要な、管理者向け API で色々ためしてみます。
既にユーザー作成時に試してますが、改めて admin-get-user でユーザー情報を取得してみます。
$ aws cognito-idp admin-get-user --user-pool-id ap-northeast-1_xxx --username sampleuser
{
"Username": "sampleuser",
"UserAttributes": [
{
"Name": "sub",
"Value": "bb64ae42-b532-4182-8efa-efc67662a345"
},
{
"Name": "dev:custom:myattribute",
"Value": "hogehoge"
}
],
"UserCreateDate": 1565708213.268,
"UserLastModifiedDate": 1565708247.72,
"Enabled": true,
"UserStatus": "CONFIRMED"
}
dev:custom:myattribute
属性の情報が参照できています。
では、次は更新を試してみます。
$ aws cognito-idp admin-update-user-attributes --user-pool-id ap-northeast-1_xxx --username sampleuser --user-attributes Name=dev:custom:myattribute,Value=fugafuga
An error occurred (InvalidParameterException) when calling the AdminUpdateUserAttributes operation: Invalid user attributes: custom:myattribute: Attribute cannot be updated.
管理者向け API でも属性の更新ができないようです。
一応、管理者向け API での削除も試してみます。
$ aws cognito-idp admin-delete-user-attributes --user-pool-id ap-northeast-1_xxx --username sampleuser --user-attribute-names dev:custom:myattribute
An error occurred (InvalidParameterException) when calling the AdminDeleteUserAttributes operation: Invalid user attributes: user.dev:custom:myattribute: Attribute cannot be updated.
というわけで削除もできません。
検証結果まとめ、結論
検証結果をまとめます。
読み取り | 更新 | 削除 | |
---|---|---|---|
クライアント API (get-user, update-attribute, delete-attribute) |
できない | できない | できない |
管理者向け API (admin-get-user, admin-update-attribute, admin-delete-attribute) |
できる | できない | できない |
というわけで、クライアント向け API では読み書きできず、管理者向け API では読み込み可能であるものの書き込みはできない状態でした。
つまり DeveloperOnlyAttribute は管理者向け API でのみ読み込むことが出来る属性と言えそうです。
DeveloperOnlyAttribute の Developer とは、 IAM のクレデンシャルを持つ開発者というようなニュアンスっぽいですね。
また、公式フォーラムに以下のような情報がありました。
AWS Developer Forums: DeveloperOnlyAttribute - what is the effect of the property?
https://forums.aws.amazon.com/thread.jspa?threadID=267841&tstart=0
This for the attributes that developer doesn't want to expose to the end users.
DeveloperOnlyAttribute はエンドユーザーに見せたくない属性に使う設定のようです。
個人的に具体的なユースケースが思い浮かびませんが・・・
ちなみに、検証で作成したリソースの後片付けは CloudFormation で作成したので、スタックを削除すれば OK です
$ aws cloudformation delete-stack --stack-name developer-only-attribute-enabled-cognito-user-pool
以上、 DeveloperOnlyAttribute について調べてみたメモでした。
こういう用途で DeveloperOnlyAttribute 使ってるとか、検証内容について指摘等あれば是非コメントください。