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.
- 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
- Loading branch information
Ronaldo Macapobre
committed
Nov 15, 2024
1 parent
40113ca
commit 3deed24
Showing
29 changed files
with
1,374 additions
and
278 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
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.