Does anyone know how to allow an api stack to acce...
# help
a
Does anyone know how to allow an api stack to access cognito identity pool created in an auth stack? I tried like this, but I get error messages I don't understand:
Copy code
this.api.attachPermissions([table, identityPool]); // identityPool is authStack.auth.identityPoolId, which console.logs to "${Token[TOKEN.390]}"
Errors I get:
Copy code
Checking deploy status...
dev-convento-signupApi | UPDATE_IN_PROGRESS | AWS::IAM::Policy | SignupApiLambdaPOSTactivationsServiceRoleDefaultPolicyDE00BD65 
dev-convento-signupApi | UPDATE_IN_PROGRESS | AWS::IAM::Policy | SignupApiLambdaPOSTregistrationsServiceRoleDefaultPolicy9B80B04C 
dev-convento-signupApi | UPDATE_FAILED | AWS::IAM::Policy | SignupApiLambdaPOSTregistrationsServiceRoleDefaultPolicy9B80B04C Actions/Condition can contain only one colon. (Service: AmazonIdentityManagement; Status Code: 400; Error Code: MalformedPolicyDocument; Request ID: 64ca5b25-90b4-4fc7-b981-cb619b3bbcd9; Proxy: null)
dev-convento-signupApi | UPDATE_FAILED | AWS::IAM::Policy | SignupApiLambdaPOSTactivationsServiceRoleDefaultPolicyDE00BD65 
dev-convento-signupApi | UPDATE_ROLLBACK_COMPLETE | AWS::IAM::Policy | SignupApiLambdaPOSTactivationsServiceRoleDefaultPolicyDE00BD65 
dev-convento-signupApi | UPDATE_ROLLBACK_COMPLETE | AWS::IAM::Policy | SignupApiLambdaPOSTregistrationsServiceRoleDefaultPolicy9B80B04C 
dev-convento-signupApi | UPDATE_FAILED | AWS::CloudFormation::Stack | dev-convento-signupApi 

 ❌  dev-convento-signupApi failed: Actions/Condition can contain only one colon. (Service: AmazonIdentityManagement; Status Code: 400; Error Code: MalformedPolicyDocument; Request ID: 64ca5b25-90b4-4fc7-b981-cb619b3bbcd9; Proxy: null)

Stack dev-convento-signupApi
  Status: failed
  Error: Actions/Condition can contain only one colon. (Service: AmazonIdentityManagement; Status Code: 400; Error Code: MalformedPolicyDocument; Request ID: 64ca5b25-90b4-4fc7-b981-cb619b3bbcd9; Proxy: null)
t
Can you pass the pool itself instead of the id
a
You mean the
cognitoCfnIdentityPool
property of Auth object?
t
Are you using the sst Auth construct?
These are the ways we support permissions, passing an arn isn't something we support
a
hmmm
well, passing the cognitoCfnIdentityPool property didn't work:
Copy code
Error: The specified permissions are not supported.
    at /home/adsc/projects/convento/node_modules/@serverless-stack/resources/src/util/permission.ts:208:13
    at Array.forEach (<anonymous>)
    at attachPermissionsToRole (/home/adsc/projects/convento/node_modules/@serverless-stack/resources/src/util/permission.ts:77:15)
    at Function.attachPermissions (/home/adsc/projects/convento/node_modules/@serverless-stack/resources/src/Function.ts:375:30)
    at /home/adsc/projects/convento/node_modules/@serverless-stack/resources/src/Api.ts:314:41
    at Array.forEach (<anonymous>)
    at Api.attachPermissions (/home/adsc/projects/convento/node_modules/@serverless-stack/resources/src/Api.ts:314:8)
    at new SignupApiStack (/home/adsc/projects/convento/stacks/SignupApistack.js:28:16)
    at Object.main (/home/adsc/projects/convento/stacks/index.js:19:27)
    at Object.<anonymous> (/home/adsc/projects/convento/.build/run.js:93:16)
t
It sounds like you need to attach an IAM policy
a
yeah, I just thought about that
gonna give it a try, thx
any idea what to put into actions?
just *?
t
Depends what exactly you want to give access to but * works
a
lol i just had to google over 20 pages to even find the service id of cognito-identity
can you see a way to get the arn to use in the resources list from the Auth sst object, or do I have to build it myself?
i think I could probably just prefix the pool id with "arnawscognito-identity:" + REGION or something
t
You're looking for the identity pool arn? Or the userPool arn?
I'm not sure about the identity pool arn
Might need to build it yourself
a
i don't have a user pool
i'm trying to make my own auth and federate it with identity pool
yeah, I constructed the arn myself and it deployed, let's see if the policy works
it seems I'm quite alone in rolling my own auth...is everyone using cognito user pools? they didn't appeal to me much, to be honest
t
I've been using cognito user pools and I don't recommend it lol. It's a terrible service and I don't think it's actually saving me any work
And does not deal with with even slightly different flows
Can you tell me more about how you're using identity pools in conjunction with your own auth? Is it for SAML?
a
nah, it's just very primitive, and I'm not even sure if it's going to work. Just a register form, then send my own activation mail with a link, then in that route call a lambda that activates the user and creates a cognito identity pool id for it, then in the client request a token for that id from cognito identity pool
i pieced various sources together, and so far i think it SHOULD work, but documentation is very sparse
t
ah got it
I hate it 🙂
My wishes are 1. Make cloudformation faster 2. Delete cognito and start over
a
haha
i'll post my setup once it works
unfortunately the ARN i constructed didn't work
I'm just copying the one from the error message for now, but will probably later need a way to get cognito identity pool arn from sst somehow
t
I'm not super familiar with identity pools so not sure how much I can help but can you check in the console what the arn is?
in aws console
a
yeah, I can probably get the correct arn for now, but I'd like it to be retrieved from sst, because if I change region or something it won't be updated otherwise
t
Yeah I meant can you look it up and see what it is and then that might help you figure out how to construct it
a
unfortunately, i still get the access denied error even with correct arn...gonna check in iam console what it actually created
t
it's probably possible to get it from the cfn resource but I don't know off the top of my head
can you share the policy you defined?
a
Copy code
// Allow the API to access the table and identity pool
      this.api.attachPermissions([
         table,
         new iam.PolicyStatement({
            actions: [
               "cognito-identity:*"
            ],
            effect: iam.Effect.ALLOW,
            resources: [
               "arn:aws:cognito-identity:eu-central-1:787845945917:identitypool/:" + identityPool,
            ],
         }),
      ]);
i can't even find this policy anywhere in IAM console
t
did you try
actions: ["*"]
Oh wait I just realized you're attaching the permissions to the api and not a function
can I see how you're defining the api?
a
Copy code
import * as sst from "@serverless-stack/resources";
import * as iam from "@aws-cdk/aws-iam";

export default class SignupApiStack extends sst.Stack {
   // Public reference to the API
   api;

   constructor(scope, id, props) {
      super(scope, id, props);

      const { table, identityPool } = props;

      // Create the API
      this.api = new sst.Api(this, "SignupApi", {
         defaultAuthorizationType: sst.ApiAuthorizationType.NONE,
         defaultFunctionProps: {
            environment: {
               TABLE_NAME: table.tableName,
               IDENTITY_POOL: identityPool,
            },
         },
         routes: {
            "POST   /registrations": "src/registration/register.main",
            "POST   /activations": "src/registration/activate.main",
         },
      });

      // Allow the API to access the table and identity pool
      this.api.attachPermissions([
         table,
         new iam.PolicyStatement({
            actions: [
               "*"
            ],
            effect: iam.Effect.ALLOW,
            resources: [
               "arn:aws:cognito-identity:eu-central-1:787845945917:identitypool/:" + identityPool,
            ],
         }),
      ]);

      // Show the API endpoint in the output
      this.addOutputs({
         ApiEndpoint: this.api.url,
      });
   }
}
same behaviour with just a * in access
t
Can you try specifying the permissions inline with the api creation
Copy code
new sst.Api(_, _, {
  permissions: [...]
})
a
ok
the thing is...I have now found the policy in IAM console, and it seems correct...
hmmm, the policy is there, but it probably doesn't grant all actions. Maybe you have to grant some functions explicitely, and they aren't covered by the *
i am pretty sure that the code works in principle, because I'm seeing the cognito policy only in the signup api roles and not in the other api roles
probably need amazon support to find out why this policy doesn't allow to call the
GetOpenIdTokenForDeveloperIdentity
call
anyway, thx for your help so far, gonna update here if I get it to work
it works with this policy statement:
Copy code
new iam.PolicyStatement({
            actions: [
               "cognito-identity:GetOpenIdTokenForDeveloperIdentity",
            ],
            effect: iam.Effect.ALLOW,
            resources: [
               "*",
            ],
         })
so it's either that I still got the resource wrong (although I copied it from the error message) or it's that
GetOpenIdTokenForDeveloperIdentity
action doesn't support resource definitions. Unfortunately, I haven't been able to find an exhaustive list of iam policy actions and which resources they support
anyway, about the complete workflow, here is an older article that has a nice diagram, which shows what I'm currently trying to achieve: https://aws.amazon.com/blogs/mobile/integrating-amazon-cognito-using-developer-authenticated-identities-an-end-to-end-example/
it isn't that complicated, I'm just struggling with the environment