This is a story about authentication and authorization for iOS applications accessing AWS resources. The story will be told in a series of topics ranging from this first one on Unauthenticated Access to AWS for iOS Apps Using AWS Amplify to basic auth (username/password), Facebook and Google federation, passwordless authentication, and we’ll even implement TOTP and some biometric authentication for accessing AWS resources from a mobile device.

Let’s begin our journey by talking about unauthenticated access to AWS resources from a mobile app.

iOS App Scenario

Imagine that you create a mobile app that accesses AWS resources, such as a photo sharing app that stores user photos in Amazon S3. A user takes a photo, saves it, and the app uploads it to a designated S3 folder. Pretty straightforward and very common, if you have no concerns over security or privacy of those users’ photos. In this scenario, the users have not authenticated with an identity provider (IdP).

Sign AWS Requests

In order to access any AWS resources from a mobile device, each request must be signed (typically using the AWS Mobile SDK) with an AWS access key. Access keys consist of two parts: an access key ID and a secret access key. The signing process helps secure requests by:

· Verifying the identity of the requester

· Protects data in transit

· Protect against potential replay attacks

AWS Identity and Access Management

IAM identities are created to provide authentication for app users in your AWS account. Identities represent the user, and can be authenticated and then authorized to perform actions in AWS. Each of these identities can be associated with one or more policies to determine what actions a user, or group member can do with AWS resources. Identities can be in the form of an AWS account root user, an IAM user, an IAM group, or as an IAM Role.

In this first article, we are tackling the unauthenticated identities approach which allows app users to securely access our AWS resources without forcing users to authenticate with an identity provider (IdP) such as Cognito User Pools (via basic auth: username/password), Facebook, Google, or any OpenID Connect (OIDC) provider. Anonymous or unauthenticated access to AWS resources is possible using Amazon Cognito Identity Pools. Identity Pools support both authenticated and unauthenticated identities. For anonymous, guest users, or whatever you want to call users that have not authenticated with an identity provider (IdP), Amazon Cognito Identity Pools provides a unique identifier and AWS credentials for these app users.

Unauthenticated Identity Access

If you don’t require (or need) to have each user authenticate with an identity provider, you can build your app so the AWS Mobile SDK requests temporary AWS credentials for each app user using an Amazon Cognito Identity Pool. So, instead of embedding a single set of credentials for all users of your app, Amazon Cognito (through web identity federation) supplies temporary credentials mapped to an AWS IAM (unauthenticated) Role that has only the permissions needed for storing photos in S3. Using an Amazon Cognito Identity provider helps you keep your AWS account secure because you don’t have to embed and distribute the security credentials with your application.

Setup Unauthenticated Access

When creating a mobile app that makes requests to any AWS service, always create an IAM Role with an associated access policy and an identity provider like Amazon Cognito (federated identity provider) to authenticate a user (or device) and map the users/device to that IAM role. We’ll use the AWS Amplify CLI to create an Unauthenticated IAM Role and associated policy with limited access to AWS resources.

Before we get started, we are going to be using the AWS Amplify Toolchain for this purpose:

$ npm install -g @aws-amplify/cli

$ amplify configure

This is a one-time install. You will need to configure the AWS CLI or create an access key and secret key for usage. Check out the Get Started tutorial for more details on this (there is a video walking you through the process).

Next, let’s initialize a project. Pick any iOS project. I’m using a single view Xcode 10 (Swift 4) project for this, but you can use whatever project you want.

$ amplify init

You will be guided through the process of setting up the project. Make sure iOS is selected at the appropriate time. Next, let’s add unauthenticated access:

The trick here is that if we ran $ amplify add auth

it would provision both unauthenticated and authenticated IAM roles and a Cognito User Pools. For demonstration purposes, I only want to show unauthenticated. To do this, I’m going to enable analytics instead and that creates the Cognito Identity Pool and associated unauthenticated IAM role without creating a User Pool.

$ amplify add analytics

Enter the default values for the app name and when prompted for “…Do you want to allow guests and unauthenticated users to send analytics events?…” Y

Client Configuration

The Podfile that you configure to install the AWS Mobile SDK must contain:

Run pod install --repo-update before you continue.

Add the following import statement to your AppDelegate or ViewController

import AWSMobileClient

Replace the return statement with following code into the bottom of the application(_:didFinishLaunchingWithOptions:) method of your app's AppDelegate.swift .

Build and Launch App

Once you launch the app, the user will be given a temporary IdentityId from Cognito Identity Pool and any AWS request will assume the Unauthenticated IAM Role that the AWS Amplify CLI created on our behalf. If you launch the IAM console and select the unauthenticated IAM Role, you’ll see the associated policy. You can update the existing policy to add or remove access. This is the role that all unauthenticated app users will assume. Once a user authenticates via an identity provider, they begin assuming the authenticated identity IAM Role. We’ll see this in the next topic when we implement authentication using Amazon Cognito User Pools for basic authentication.