-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: http api - iam authorizer #14853
Closed
Closed
Changes from 3 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
1ee3415
feat: http api - iam authorizer
iRoachie ea2deea
Merge branch 'master' into ft/http-api-iam-authorizer
iRoachie 604cc1d
test: add unit test for default integration
iRoachie e1632fb
Merge branch 'master' into ft/http-api-iam-authorizer
iRoachie 174c621
Merge branch 'master' into ft/http-api-iam-authorizer
iRoachie 39d3d6e
Merge branch 'master' into ft/http-api-iam-authorizer
iRoachie File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
packages/@aws-cdk/aws-apigatewayv2-authorizers/lib/http/iam.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { HttpRouteAuthorizerConfig, IHttpRouteAuthorizer } from '@aws-cdk/aws-apigatewayv2'; | ||
|
||
/** | ||
* Authorize Http Api routes with IAM using sigv4 to sign request | ||
*/ | ||
export class HttpIamAuthorizer implements IHttpRouteAuthorizer { | ||
public bind(): HttpRouteAuthorizerConfig { | ||
return { | ||
authorizationType: 'AWS_IAM', | ||
}; | ||
} | ||
} |
57 changes: 57 additions & 0 deletions
57
packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/iam.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import '@aws-cdk/assert-internal/jest'; | ||
import { ABSENT } from '@aws-cdk/assert-internal'; | ||
import { HttpApi, IHttpRouteIntegration, HttpRouteIntegrationBindOptions, PayloadFormatVersion, HttpIntegrationType } from '@aws-cdk/aws-apigatewayv2'; | ||
import { Stack } from '@aws-cdk/core'; | ||
import { HttpIamAuthorizer } from '../../lib/http/iam'; | ||
|
||
describe('HttpIamAuthorizer', () => { | ||
test('default', () => { | ||
// GIVEN | ||
const stack = new Stack(); | ||
const api = new HttpApi(stack, 'HttpApi'); | ||
|
||
const authorizer = new HttpIamAuthorizer(); | ||
|
||
// WHEN | ||
api.addRoutes({ | ||
integration: new DummyRouteIntegration(), | ||
path: '/books', | ||
authorizer, | ||
}); | ||
|
||
// THEN | ||
expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { | ||
AuthorizationType: 'AWS_IAM', | ||
AuthorizerId: ABSENT, | ||
}); | ||
}); | ||
|
||
test('default integration', () => { | ||
// GIVEN | ||
const stack = new Stack(); | ||
const authorizer = new HttpIamAuthorizer(); | ||
|
||
// WHEN | ||
new HttpApi(stack, 'HttpApi', { | ||
defaultAuthorizer: authorizer, | ||
defaultIntegration: new DummyRouteIntegration(), | ||
}); | ||
|
||
// THEN | ||
expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { | ||
AuthorizationType: 'AWS_IAM', | ||
AuthorizerId: ABSENT, | ||
}); | ||
}); | ||
}); | ||
|
||
|
||
class DummyRouteIntegration implements IHttpRouteIntegration { | ||
public bind(_: HttpRouteIntegrationBindOptions) { | ||
return { | ||
payloadFormatVersion: PayloadFormatVersion.VERSION_2_0, | ||
type: HttpIntegrationType.HTTP_PROXY, | ||
uri: 'some-uri', | ||
}; | ||
} | ||
} |
258 changes: 258 additions & 0 deletions
258
packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.iam.expected.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,258 @@ | ||
{ | ||
"Resources": { | ||
"MyHttpApi8AEAAC21": { | ||
"Type": "AWS::ApiGatewayV2::Api", | ||
"Properties": { | ||
"Name": "MyHttpApi", | ||
"ProtocolType": "HTTP" | ||
} | ||
}, | ||
"MyHttpApiDefaultStageDCB9BC49": { | ||
"Type": "AWS::ApiGatewayV2::Stage", | ||
"Properties": { | ||
"ApiId": { | ||
"Ref": "MyHttpApi8AEAAC21" | ||
}, | ||
"StageName": "$default", | ||
"AutoDeploy": true | ||
} | ||
}, | ||
"MyHttpApiGETIAMAuthorizerIntegMyHttpApiGET271B2CE5PermissionE3A1E0E1": { | ||
"Type": "AWS::Lambda::Permission", | ||
"Properties": { | ||
"Action": "lambda:InvokeFunction", | ||
"FunctionName": { | ||
"Fn::GetAtt": [ | ||
"lambda8B5974B5", | ||
"Arn" | ||
] | ||
}, | ||
"Principal": "apigateway.amazonaws.com", | ||
"SourceArn": { | ||
"Fn::Join": [ | ||
"", | ||
[ | ||
"arn:", | ||
{ | ||
"Ref": "AWS::Partition" | ||
}, | ||
":execute-api:", | ||
{ | ||
"Ref": "AWS::Region" | ||
}, | ||
":", | ||
{ | ||
"Ref": "AWS::AccountId" | ||
}, | ||
":", | ||
{ | ||
"Ref": "MyHttpApi8AEAAC21" | ||
}, | ||
"/*/*/" | ||
] | ||
] | ||
} | ||
} | ||
}, | ||
"MyHttpApiGETHttpIntegration6f095b8469365f72e33fa33d9711b140516EBE31": { | ||
"Type": "AWS::ApiGatewayV2::Integration", | ||
"Properties": { | ||
"ApiId": { | ||
"Ref": "MyHttpApi8AEAAC21" | ||
}, | ||
"IntegrationType": "AWS_PROXY", | ||
"IntegrationUri": { | ||
"Fn::GetAtt": [ | ||
"lambda8B5974B5", | ||
"Arn" | ||
] | ||
}, | ||
"PayloadFormatVersion": "2.0" | ||
} | ||
}, | ||
"MyHttpApiGETE0EFC6F8": { | ||
"Type": "AWS::ApiGatewayV2::Route", | ||
"Properties": { | ||
"ApiId": { | ||
"Ref": "MyHttpApi8AEAAC21" | ||
}, | ||
"RouteKey": "GET /", | ||
"AuthorizationType": "AWS_IAM", | ||
"Target": { | ||
"Fn::Join": [ | ||
"", | ||
[ | ||
"integrations/", | ||
{ | ||
"Ref": "MyHttpApiGETHttpIntegration6f095b8469365f72e33fa33d9711b140516EBE31" | ||
} | ||
] | ||
] | ||
} | ||
} | ||
}, | ||
"lambdaServiceRole494E4CA6": { | ||
"Type": "AWS::IAM::Role", | ||
"Properties": { | ||
"AssumeRolePolicyDocument": { | ||
"Statement": [ | ||
{ | ||
"Action": "sts:AssumeRole", | ||
"Effect": "Allow", | ||
"Principal": { | ||
"Service": "lambda.amazonaws.com" | ||
} | ||
} | ||
], | ||
"Version": "2012-10-17" | ||
}, | ||
"ManagedPolicyArns": [ | ||
{ | ||
"Fn::Join": [ | ||
"", | ||
[ | ||
"arn:", | ||
{ | ||
"Ref": "AWS::Partition" | ||
}, | ||
":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" | ||
] | ||
] | ||
} | ||
] | ||
} | ||
}, | ||
"lambda8B5974B5": { | ||
"Type": "AWS::Lambda::Function", | ||
"Properties": { | ||
"Code": { | ||
"S3Bucket": { | ||
"Ref": "AssetParameters1fd1c15cb7d5e2e36a11745fd10b4b7c3ca8eb30642b41954630413d2b913cdaS3Bucket2E6D85D3" | ||
}, | ||
"S3Key": { | ||
"Fn::Join": [ | ||
"", | ||
[ | ||
{ | ||
"Fn::Select": [ | ||
0, | ||
{ | ||
"Fn::Split": [ | ||
"||", | ||
{ | ||
"Ref": "AssetParameters1fd1c15cb7d5e2e36a11745fd10b4b7c3ca8eb30642b41954630413d2b913cdaS3VersionKey22B8E7C6" | ||
} | ||
] | ||
} | ||
] | ||
}, | ||
{ | ||
"Fn::Select": [ | ||
1, | ||
{ | ||
"Fn::Split": [ | ||
"||", | ||
{ | ||
"Ref": "AssetParameters1fd1c15cb7d5e2e36a11745fd10b4b7c3ca8eb30642b41954630413d2b913cdaS3VersionKey22B8E7C6" | ||
} | ||
] | ||
} | ||
] | ||
} | ||
] | ||
] | ||
} | ||
}, | ||
"Role": { | ||
"Fn::GetAtt": [ | ||
"lambdaServiceRole494E4CA6", | ||
"Arn" | ||
] | ||
}, | ||
"Handler": "index.handler", | ||
"Runtime": "nodejs12.x" | ||
}, | ||
"DependsOn": [ | ||
"lambdaServiceRole494E4CA6" | ||
] | ||
}, | ||
"testuser14267055": { | ||
"Type": "AWS::IAM::User", | ||
"Properties": { | ||
"ManagedPolicyArns": [ | ||
{ | ||
"Fn::Join": [ | ||
"", | ||
[ | ||
"arn:", | ||
{ | ||
"Ref": "AWS::Partition" | ||
}, | ||
":iam::aws:policy/AmazonAPIGatewayInvokeFullAccess" | ||
] | ||
] | ||
} | ||
] | ||
} | ||
}, | ||
"accesskey": { | ||
"Type": "AWS::IAM::AccessKey", | ||
"Properties": { | ||
"UserName": { | ||
"Ref": "testuser14267055" | ||
} | ||
} | ||
} | ||
}, | ||
"Parameters": { | ||
"AssetParameters1fd1c15cb7d5e2e36a11745fd10b4b7c3ca8eb30642b41954630413d2b913cdaS3Bucket2E6D85D3": { | ||
"Type": "String", | ||
"Description": "S3 bucket for asset \"1fd1c15cb7d5e2e36a11745fd10b4b7c3ca8eb30642b41954630413d2b913cda\"" | ||
}, | ||
"AssetParameters1fd1c15cb7d5e2e36a11745fd10b4b7c3ca8eb30642b41954630413d2b913cdaS3VersionKey22B8E7C6": { | ||
"Type": "String", | ||
"Description": "S3 key for asset version \"1fd1c15cb7d5e2e36a11745fd10b4b7c3ca8eb30642b41954630413d2b913cda\"" | ||
}, | ||
"AssetParameters1fd1c15cb7d5e2e36a11745fd10b4b7c3ca8eb30642b41954630413d2b913cdaArtifactHash82A279EA": { | ||
"Type": "String", | ||
"Description": "Artifact hash for asset \"1fd1c15cb7d5e2e36a11745fd10b4b7c3ca8eb30642b41954630413d2b913cda\"" | ||
} | ||
}, | ||
"Outputs": { | ||
"apiurl": { | ||
"Value": { | ||
"Fn::Join": [ | ||
"", | ||
[ | ||
"https://", | ||
{ | ||
"Ref": "MyHttpApi8AEAAC21" | ||
}, | ||
".execute-api.", | ||
{ | ||
"Ref": "AWS::Region" | ||
}, | ||
".", | ||
{ | ||
"Ref": "AWS::URLSuffix" | ||
}, | ||
"/" | ||
] | ||
] | ||
} | ||
}, | ||
"accesskey": { | ||
"Value": { | ||
"Ref": "accesskey" | ||
} | ||
}, | ||
"secretaccesskey": { | ||
"Value": { | ||
"Fn::GetAtt": [ | ||
"accesskey", | ||
"SecretAccessKey" | ||
] | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @iRoachie -
This does not feel like the right approach to solving IAM authorizers. Just having an
HttpIamAuthorizer
class to set theAuthorizationType
and then leaving it up to the user to correctly configure the IAM policy feels sub-optimal.I would suggest going with an alternate approach. Here's my proposal written in the form of what the user experience will be -
This should, under the hood, automatically set the
AuthorizationType
toAWS_IAM
and attach the relevant IAM permissions to the principal.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was going based on usage and what was requested in #10534.
As far as I understand the use case for IAM Authorization is to set policies on individual users to grant access to all/some routes.
I see where you are going with your suggestion however I think this can be an add-on to what is currently in this PR. If we only change the authorizationType when grantInvoke is called on a route then we automatically rule out scenarios where user permissions are managed outside of cdk/cloudformation (which is pretty common for physical users).
So just to be clear they're two things here: