This is a draft proposal of the API authentication framework that can be used by any developer for a web application or REST API. The source diagrams can be found in Lucid Charts here.
Key Objectives
- This pattern shall be general enough to be reusable for all common web applications and REST APIs
- The pattern shall be secure and expandable to support multiple authentication requirements, including MFA and user self service
- The pattern shall support authentication through SAML v2 or OIDC, for example connecting to Roche SSO for authentication
- The pattern shall not rely on developers code for authentication
Key Components
- AWS Cognito is used to manage user pools for authentication
- AWS API Gateway is used to front the service and enforce the authentication mechanism
- Web Application or REST API is the code created by a developer that requires authentication
User Case: Framework for API Authentication without Authorization
<!— image: image (from original wiki uploads) —>
Data Flow
- A user or a machine makes an authentication call to AWS Cognito to acquire the required token that will be used to authenticate the API Gateway. The user is authenticated against a Cognito user pool. A dedicated user pool is defined for each application or api. If authentication is successful, a JWT ID token, access token, and refresh token is generated as a response.
- The access token is then passed by the user or machine as a part of the requests Authorization header to make the API call to service through the API Gateway.
- The evaluation occurs in the API Gateway as a part of the API Gateway Authorizers Cognito configuration. The API call succeeds only if the required token is supplied and the supplied token is valid, otherwise, the client isn’t authorized to make the call because the client did not have credentials that could be authorized. The traffic is dropped at this point at the API Gateway layer.
- If the token can be validated the request is forwarded to the service.
Components
AWS Cognito
- AWS Cognito is used to define a user pool. User pools are user directories that provide sign-in options for your app users. Currently the users have be setup in the pool to authenticate. To obtain the access token, a client must successfully authenticate to Cognito by passing the configured user pool ID, client ID, and any client secret must be provided by the client.
- The user pool name is required as a part of the authorizer configuration in API Gateway. See here for more detail.
AWS API Gateway
- AWS API Gateway is an AWS service for creating, publishing, maintaining, monitoring, and securing REST, HTTP, and WebSocket APIs at any scale.
- In API Gateway, a resource server needs to be configured. A resource server is a server for access-protected resources. It handles authenticated requests from an app that has an access token. Typically the resource server provides a CRUD API for making these access requests. The client passes the access token in the API call to the resource server. The resource server inspects the access token to determine if access should be granted.
- The resource server configuration includes a resource server name, a resource server identifier and a scope name and description. When a client app requests a custom scope in any of the OAuth2.0 flows, it must request the full identifier for the scope, which is
resourceServerIdentifier/scopeName. For example, if the resource server identifier is https://awesomeapp.gred.ai and the scope name is file.read, the client app must requesthttps://awesomeapp.gred.ai/file.read at runtime.See here for more details.
User Case: Framework for API Authentication with Authorization
<!— image: image (from original wiki uploads) —>
Data Flow
- A user or a machine makes an authentication call to AWS Cognito to acquire the required token that will be used to authenticate the API Gateway. The user is authenticated against a Cognito user pool. A dedicated user pool is defined for each application or api. If authentication is successful, a JWT ID token, access token, and refresh token is generated as a response.
- The access token is then passed by the user or machine as a part of the requests Authorization header to make the API call to service through the API Gateway.
- API Gateway forwards the request to a Lambda authorizer—also known as a custom authorizer. The Lambda authorizer verifies the Amazon Cognito JWT using the Amazon Cognito public key. On initial Lambda invocation, the public key is downloaded from Amazon Cognito and cached. Subsequent invocations will use the public key from the cache.
- The Lambda authorizer looks up the Amazon Cognito group that the user belongs to in the JWT and does a lookup in Amazon DynamoDB to get the policy that’s mapped to the group. If there is no policy mapped to the Cognito group the Lambda authorizer will generate a deny policy and request will be denied.
- Lambda returns the policy and—optionally—context to API Gateway. The context is a map containing key-value pairs that you can pass to the upstream service. It can be additional information about the user, the service, or anything that provides additional information to the upstream service.
- The request is forwarded to the service.