forked from bcgov/supreme-court-viewer
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
JASPER-217: Integrate Authorizer to API Gateway (#69)
- Fixed error in publish lambda GHA - Fixed failing build in Publish Lambda Functions GHA - Added Authorizer and Rotate Key Lambda Functions - Update Terraform code to support Authorizer - Added implementation to restart ECS service when key is rotated - Updates to TF to allow lambda to update secret and restart ECS service - Use x-origin-verify header and pass to http client - Update devcontainer to force .tf files to be formatted by TF extension - Added APIGW Settings for logging - Added lambda mem size default to 512M --------- Co-authored-by: Ronaldo Macapobre <[email protected]>
- Loading branch information
1 parent
a31f1ea
commit 4c637b9
Showing
31 changed files
with
1,404 additions
and
287 deletions.
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
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
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
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
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
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,3 @@ | ||
{ | ||
"semi": true | ||
} |
This file was deleted.
Oops, something went wrong.
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,105 @@ | ||
import { Logger } from "@aws-lambda-powertools/logger"; | ||
import { | ||
APIGatewayAuthorizerResult, | ||
APIGatewayRequestAuthorizerEvent, | ||
Context, | ||
PolicyDocument, | ||
StatementEffect, | ||
} from "aws-lambda"; | ||
import { v4 as uuidv4 } from "uuid"; | ||
import SecretsManagerService from "../../../services/secretsManagerService"; | ||
|
||
const X_ORIGIN_VERIFY_HEADER = "x-origin-verify"; | ||
|
||
export const handler = async ( | ||
event: APIGatewayRequestAuthorizerEvent, | ||
context: Context | ||
): Promise<APIGatewayAuthorizerResult> => { | ||
console.log(`Event: ${JSON.stringify(event, null, 2)}`); | ||
console.log(`Context: ${JSON.stringify(context, null, 2)}`); | ||
|
||
const correlationId: string = event.requestContext.requestId || uuidv4(); | ||
const logger = new Logger({ | ||
serviceName: "auth.authorizer", | ||
}); | ||
|
||
try { | ||
if (!event.headers) { | ||
logger.error("headers is missing."); | ||
throw new Error("Error: invalid token"); | ||
} | ||
|
||
// x-verify-origin should be set by the caller | ||
if (!(X_ORIGIN_VERIFY_HEADER in event.headers)) { | ||
logger.error(`${X_ORIGIN_VERIFY_HEADER} not found in headers.`); | ||
throw new Error("Error: invalid token"); | ||
} | ||
|
||
// Extract the token from the request | ||
const verifyToken = event.headers[X_ORIGIN_VERIFY_HEADER]; | ||
const smService = new SecretsManagerService(); | ||
const secretStringJson = await smService.getSecret( | ||
process.env.VERIFY_SECRET_NAME! | ||
); | ||
|
||
let verifyTokenfromSecretManager = ""; | ||
if (secretStringJson) { | ||
verifyTokenfromSecretManager = JSON.parse(secretStringJson).verifyKey; | ||
logger.info( | ||
"Authorization token from secret manager", | ||
verifyTokenfromSecretManager | ||
); | ||
} else { | ||
logger.error("Secret not found in secret manager"); | ||
throw new Error("Error: invalid token"); | ||
} | ||
|
||
if (verifyToken !== verifyTokenfromSecretManager) { | ||
logger.error("Authorization token not valid"); | ||
throw new Error("Error: invalid token"); | ||
} | ||
|
||
const policy = generatePolicy( | ||
correlationId, | ||
"user", | ||
"Allow", | ||
event.methodArn | ||
); | ||
|
||
logger.info(JSON.stringify(policy)); | ||
|
||
return policy; | ||
} catch (error) { | ||
logger.error(error); | ||
|
||
throw new Error("Unauthorized"); | ||
} | ||
}; | ||
|
||
const generatePolicy = ( | ||
correlationId: string, | ||
principalId: string, | ||
effect: StatementEffect, | ||
resource: string | ||
): APIGatewayAuthorizerResult => { | ||
const policyDocument: PolicyDocument = { | ||
Version: "2012-10-17", | ||
Statement: [ | ||
{ | ||
Action: "execute-api:Invoke", | ||
Effect: effect, | ||
Resource: resource, | ||
}, | ||
], | ||
}; | ||
|
||
const authResponse: APIGatewayAuthorizerResult = { | ||
principalId, | ||
context: { | ||
correlation_id: correlationId, | ||
}, | ||
policyDocument, | ||
}; | ||
|
||
return authResponse; | ||
}; |
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,63 @@ | ||
import { Logger } from "@aws-lambda-powertools/logger"; | ||
import { APIGatewayEvent, APIGatewayProxyResult, Context } from "aws-lambda"; | ||
import { v4 as uuidv4 } from "uuid"; | ||
import ECSService from "../../../services/ecsService"; | ||
import SecretsManagerService from "../../../services/secretsManagerService"; | ||
|
||
export const handler = async ( | ||
event: APIGatewayEvent, | ||
context: Context | ||
): Promise<APIGatewayProxyResult> => { | ||
console.log(`Event: ${JSON.stringify(event, null, 2)}`); | ||
console.log(`Context: ${JSON.stringify(context, null, 2)}`); | ||
|
||
const logger = new Logger({ | ||
serviceName: "auth.rotate-key", | ||
}); | ||
|
||
try { | ||
logger.info("Rotating verifyKey."); | ||
await updateSecret(); | ||
logger.info("Successfully rotated verifyKey"); | ||
|
||
logger.info("Restarting ECS Services to pickup updated VerifyKey."); | ||
await restartECSServices(); | ||
logger.info("Restart completed."); | ||
|
||
return { | ||
statusCode: 200, | ||
body: JSON.stringify({ | ||
message: | ||
"Successfully rotated the key and restarted the ECS Service/TD", | ||
}), | ||
}; | ||
} catch (error) { | ||
logger.error(error); | ||
|
||
return { | ||
statusCode: 500, | ||
body: JSON.stringify({ | ||
message: | ||
"Something went wrong when updating the key and restarting the ECS Service/TD", | ||
}), | ||
}; | ||
} | ||
}; | ||
|
||
const updateSecret = async () => { | ||
const smService = new SecretsManagerService(); | ||
const newGuid = uuidv4(); | ||
|
||
await smService.updateSecret( | ||
process.env.VERIFY_SECRET_NAME!, | ||
JSON.stringify({ verifyKey: newGuid }) | ||
); | ||
}; | ||
|
||
const restartECSServices = async () => { | ||
const ecsService = new ECSService(process.env.CLUSTER_NAME!); | ||
|
||
const services = await ecsService.getECSServices(); | ||
|
||
await ecsService.restartServices(services); | ||
}; |
Oops, something went wrong.