Restricting Unauthenticated  AWS Access by Referer and IP, similar to Google API Keys
Tags: aws, cognito, googlecloud, maps
Published: 2021-07-24 03:08:22

For anyone who has used Google's JavaScript Map APIs, you know you use an API key to authenticate but you [can lock down the API key so that only requests from certain referers or IPs are accepted](https://developers.google.com/maps/api-security-best-practices).

In experimenting with [creating a simple web-based map for the AWS Builders Community using the new AWS Location Service](https://dev.to/aws-builders/aws-location-service-where-my-aws-community-builders-at-e02), it wasn't intuitive to me how to lock down the [unauthenticated access provided by the Cognito Identity Pool as described in the AWS Location Service developer guide](https://docs.aws.amazon.com/location/latest/developerguide/authenticating-using-cognito.html) and I couldn't find any advice in the developer guides.

Andrew Johnson pointed me in the right direction and there are conditions that can be added to the Cognito Identity Pool unauthenticated role for both referer, IP addresses, and [many others](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html).  

I would hope the Amazon Location Service Developer Guide is eventually updated with this advice as this should definitely be a best practice similar to what is recommended for Google Maps.

That being said, this does not prevent a sophisticated user from spoofing the referer and/or IP and any anonymous access should be minimized to the absolute least privilege.  Here is the warning from the [AWS conditions page](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html):

> [The aws:Referer] key should be used carefully. It is dangerous to include a publicly known referer header value. Unauthorized parties can use modified or custom browsers to provide any aws:referer value that they choose. As a result, aws:referer should not be used to prevent unauthorized parties from making direct AWS requests. It is offered only to allow customers to protect their digital content, such as content stored in Amazon S3, from being referenced on unauthorized third-party sites.

Check out the examples below.

### Restricting by referer
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "MapsReadOnly",
            "Effect": "Allow",
            "Action": [
                "geo:GetMapStyleDescriptor",
                "geo:GetMapGlyphs",
                "geo:GetMapSprites",
                "geo:GetMapTile"
            ],
            "Resource": "arn:aws:geo:us-west-2:xxxxxxx:map/my-map",
            "Condition": {
                "StringLike": {
                    "aws:Referer": [
                        "http://www.example.com/*",
                        "http://example.com/*"
                    ]
                }
            }
        }
    ]
}
```

### Restricting by IP
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "MapsReadOnly",
            "Effect": "Allow",
            "Action": [
                "geo:GetMapStyleDescriptor",
                "geo:GetMapGlyphs",
                "geo:GetMapSprites",
                "geo:GetMapTile"
            ],
            "Resource": "arn:aws:geo:us-west-2:xxxxxxx:map/my-map",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "123.45.67.89"
                }
            }
        }
    ]
}
```

I've tried this out and it works great and have since added it to my [public map project(s)](http://acbmap.humbleg.com/aws/).  

Let me know if you have any other best practices for least privilege permissions for public/unauthenticated users.

Want more?  [Follow me on Twitter](https://twitter.com/JDonboch) and [connect with me on Linked In](https://www.linkedin.com/in/jareddonboch/)!