-
Notifications
You must be signed in to change notification settings - Fork 3
Authorization
API Gateway has three different mechanisms for controlling access to API endpoints, all of which are supported by Osiris. These are:
- IAM (AWS Identity and Access Management)
- Cognito Users Pools
- Lambda Authorizer (formerly known as a custom authorizer)
By default, the endpoints in an Osiris application do not require authorization and can be invoked by anyone. If you need to control access to endpoints they should be placed inside an auth block in the API definition. Consider this API:
val api = api<ComponentsProvider> {
get("/helloworld") {
"hello, world!"
}
auth(IamAuth) {
get("/private") {
"hello, authenticated user!"
}
}
}The endpoint /helloworld is public as it is not inside the auth block. The endpoint /private is protected by IAM authorization and can only be invoked by an authorized caller.
The type of authorization is specified by the argument to the auth function. This must be a subtype of the Auth interface. The arguments for the three types of authorization are the singleton objects IamAuth, CognitoUserPoolsAuth and CustomAuth.
Note: currently it is not possible to use CognitoUserPoolsAuth and CustomAuth in the same API. It is also not possible to use multiple user pools or multiple lambda authorizers in the same API.
IAM (Identity and Access Management) is the standard AWS service used to control access to AWS resources. If an endpoint is protected with IAM authorization the caller must provide their IAM access keys as headers on the request. This allows a policy to be found giving the user permission to invoke the resource. See the AWS documentation for details.
Cognito is an AWS service for maintaining a user directory and providing a sign-in service. If an endpoint is protected with CognitoUserPoolsAuth then the user must authenticate with a Cognito User Pool before making a request to the endpoint.
When the user authenticates, Cognito returns a token. This token must be sent in a header when making a request to the endpoint. When it receives this token, API Gateway validates it with the user pool and if the token is valid the caller is allowed to invoke the endpoint.
The validation logic is carried out by an authorizer attached to the API. This is created automatically by Osiris if any of the endpoints are protected by CognitoUserPoolsAuth. However, Osiris does not automatically create the user pool. A user pool is a complicated resource with many options and creating one is beyond the scope of Osiris.
The user pool can be created in two ways:
- Independently of the Osiris application - manually in the AWS console or using CloudFormation
- As part of the Osiris application, using a hand-written CloudFormation template
See here for details of setting up a Cognito User Pool for use with API Gateway.
If the user pool is created outside the Osiris project then its ARN (unique identifier) must be specified in the application configuration. The authConfig property of the ApplicationConfig must be an instance of AuthConfig.CognitoUserPools. For example:
val config = ApplicationConfig(
authConfig = AuthConfig.CognitoUserPools("arn:aws:cognito-idp:eu-west-1:43215678:userpool/MyUserPool")
...
)TODO link to cognito example project
If the user pool is defined in the same project as the API it should be defined in the CloudFormation file root.template. See here for details of creating AWS resources in the project using CloudFormation.
The ARN (unique identifier) of the user pool must be passed to the template generated by Osiris so it can be used by API Gateway. It must be passed as a parameter to the generated template named CognitoUserPoolArn.
TODO link to cognito example project
When an endpoint is protected by a lambda authorizer, API Gateway invokes a lambda function to determine whether the user is permitted to invoke the endpoint. If the user is authorized then this lambda function returns an IAM policy with permissions allowing the the user to invoke the endpoint.
The authorization lambda function must be provided by the user. API Gateway is connected to the lambda via an authorizer. This authorizer is created automatically by Osiris.
The authorization lambda function can be created in two ways:
- Independently of the Osiris application - manually in the AWS console or using CloudFormation
- As part of the Osiris application, using a hand-written CloudFormation template
If the lambda is defined in the same project as the API it should be defined in the CloudFormation file root.template. See here for details of creating AWS resources in the project using CloudFormation.
The ARN (unique identifier) of the lambda must be passed to the template generated by Osiris so it can be used by API Gateway. It must be passed as a parameter to the generated template named CustomAuthArn.
The custom-auth1 module in the Osiris Examples project demonstrates how to do this.
If the authorization lambda is created outside the Osiris project then its ARN (unique identifier) must be specified in the application configuration. The authConfig property of the ApplicationConfig must be an instance of AuthConfig.Custom. For example:
val config = ApplicationConfig(
authConfig = AuthConfig.Custom("arn:aws:lambda:eu-west-1:43218765:function:foo")
...
)The custom-auth2 module in the Osiris Examples project demonstrates how to do this.
See the AWS documentation for the details of how to create an authorization lambda.
Note: API Gateway support two different types of lambda authorization, TOKEN and REQUEST. Currently only TOKEN is supported. See this issue for details of support for REQUEST authorization.