amazon-web-servicesgoogle-oauthamazon-cognitoaws-amplifygoogle-domain-api

Restrict login to Enterprise Google Domain for AWS Federated Identity Pool


I'm using a federation identity pools with aws-amplify (https://aws.github.io/aws-amplify/media/authentication_guide#enabling-federated-identities) and I'd like to restrict the scope of domains to just my google domain organization (ex. johndoe@foobar.com).

There doesn't seem to be a way to lock it down on either the Google API console or the AWS Cognito Identity Pool settings, just a hint that an hd parameter can be appended to the google request to restrict it by domain (which would still require modifying the aws-amplify core package), and it still wouldn't be secure since anyone could just make the same request without the hd and gain access to cognito.

My question is this: is there a way to restrict a google oauth key to only allow @foobar.com email addresses, or to implement the same restriction with aws cognito?


Solution

  • I believe I found a solution (from several quick tests it seems to be working fine)

    Don't try to control the hosted domain part via the Trust Relationship in the Role.

    • Go to: Cognito / Edit Identity Pool / Authentication Providers

    • Select Google+

    • In "Authenticated role selection" select "Choose role with Rules"

    • Now require claim "hd" to be "equals" to <your-domain>

    • set "Role resolution" to "DENY"

    Source: https://forums.aws.amazon.com/thread.jspa?messageID=527303

    Here's a cloudformation stack to set everything (identity pool, roles, etc.) in one go. YOU NEED TO MAKE THE NECESSARY ADJUSTMENTS at all places marked with an EDIT HERE: comment.

    AWSTemplateFormatVersion : 2010-09-09
    Description : "An Identity Pool stack which uses Google for sign-in"
    
    
    Resources:
      IdentityPool:
        Type: AWS::Cognito::IdentityPool
        Properties:
          IdentityPoolName: identity_pool_a
          AllowUnauthenticatedIdentities: false
          SupportedLoginProviders: 
            # EDIT HERE:
            "accounts.google.com": "11111111111-22222222222222222222222222222222.apps.googleusercontent.com"
    
      IdentityForbiddenRole:
        Type: AWS::IAM::Role
        Properties:
          MaxSessionDuration: 3600
          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 IdentityPool
                  ForAnyValue:StringLike:
                    "cognito-identity.amazonaws.com:amr": unauthenticated
          Policies:
            - PolicyName: None
              PolicyDocument:
                Version: "2012-10-17"
                Statement:
                  - Effect: Deny
                    Action: "*"
                    Resource: "*"
    
      IdentityAllowedRole:
        Type: AWS::IAM::Role
        Properties:
          MaxSessionDuration: 3600
          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 IdentityPool
                  ForAnyValue:StringLike:
                    "cognito-identity.amazonaws.com:amr": authenticated
          Policies:
            - PolicyName: UserPermissions
              PolicyDocument:
                Version: "2012-10-17"
                Statement:
                  - Effect: Allow
                    # EDIT HERE:
                    Action: "s3:GetObject"
                    # EDIT HERE:
                    Resource: "arn:aws:s3:::my-bucket/*"
    
      RoleAttachment:
        Type: AWS::Cognito::IdentityPoolRoleAttachment
        Properties:
          IdentityPoolId: !Ref IdentityPool
          Roles: 
            unauthenticated: !GetAtt IdentityForbiddenRole.Arn
            authenticated: !GetAtt IdentityForbiddenRole.Arn
          RoleMappings: 
            accounts.google.com:
              AmbiguousRoleResolution: Deny
              Type: Rules
              RulesConfiguration:
                Rules:
                  - Claim: hd
                    MatchType: Equals
                    # EDIT HERE:
                    Value: mydomain.com
                    RoleARN: !GetAtt IdentityAllowedRole.Arn