I have a CloudWatch Evidently project that I want to use to control feature flags on a public web UI. Since I can't embed durable AWS credentials on the client-side app, I understand Cognito is the recommended tool to allow unauthenticated access to AWS services.
I've created the Cognito Identity Pool, IAM role, and linkage between the two using this CloudFormation template:
CognitoIdentityPool:
Type: AWS::Cognito::IdentityPool
Properties:
AllowClassicFlow: True
AllowUnauthenticatedIdentities: True
IdentityPoolName: my-identity-pool
UIIAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Federated: cognito-identity.amazonaws.com
Action: sts:AssumeRoleWithWebIdentity
Condition:
StringEquals:
cognito-identity.amazonaws.com:aud: !Ref CognitoIdentityPool
ForAnyValue:StringLike:
cognito-identity.amazonaws.com:amr: unauthenticated
MaxSessionDuration: 3600
Policies:
- PolicyName: root
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- cognito-identity:GetCredentialsForIdentity
- evidently:ListFeatures
- evidently:EvaluateFeature
Resource: '*'
IdentityPoolRoleAttachment:
Type: AWS::Cognito::IdentityPoolRoleAttachment
Properties:
IdentityPoolId: !Ref CognitoIdentityPool
Roles:
unauthenticated: !GetAtt UIIAMRole.Arn
The console UI shows everything created as expected: guest access is enabled on the Identity Pool, associated with the created IAM role, and the role has a policy including the correct Evidently rights.
But when I try to receive the credentials, it says the role does not have rights to use the Evidently feature:
$ aws cognito-identity get-id --identity-pool us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
{
"IdentityId": "us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
$ aws cognito-identity get-credentials-for-identity --identity-id us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
{
"IdentityId": "us-east-1:xxxxxxxxxxxxxxxxxxxxx",
"Credentials": {
"AccessKeyId": "xxxxxxxxxxxxxxxxxxxxx",
"SecretKey": "xxxxxxxxxxxxxxxxxxxxx",
"SessionToken": "xxxxxxxxxxxxxxxxxxxxx",
"Expiration": "2023-11-30T11:03:53-05:00"
}
}
$ export AWS_ACCESS_KEY_ID=xxxxxxxxxxxxxxxxxxxxx
$ export AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxx
$ export AWS_SESSION_TOKEN=xxxxxxxxxxxxxxxxxxxxx
$ aws evidently list-features --project my-evidently-project
An error occurred (AccessDeniedException) when calling the ListFeatures operation: User: arn:aws:sts::xxxxxxxxxxxx:assumed-role/my-role-UIIAMRole-xxxxxxxxxx/CognitoIdentityCredentials is not authorized to perform: evidently:ListFeatures on resource: arn:aws:evidently:us-east-1:xxxxxxxxxxxx:project/my-evidently-project/feature/*
I've also tried obtaining and using the credentials using the Node SDK:
const evidentlyClient = new EvidentlyClient({
region: 'us-east-1',
credentials: fromCognitoIdentityPool({
identityPoolId: 'us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
clientConfig: { region: 'us-east-1' }
})
})
const featureResp = await evidentlyClient.send(
new ListFeaturesCommand({
project: 'arc-editorial-search-api'
})
)
which also fails with the same error.
Can anyone tell me what I'm doing wrong?
I believe the approach in the question is using the enhanced flow, which has limited rights, per this document. The following commands work, which I think corresponds to the basic flow:
and using the sdk: