Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
89461cc
CCM-8897_jwks-key-rotation
mark-r-bjss Mar 18, 2025
df0dcdc
CCM-8897: merge
mark-r-bjss Mar 21, 2025
5f95c49
CCM-8897: merge
mark-r-bjss Mar 28, 2025
239374d
CCM-8897: merge
mark-r-bjss Apr 1, 2025
c03f0ea
CCM-8897: jwks key rotation WIP
mark-r-bjss Apr 2, 2025
0a8fb85
CCM-8897: create acct level shared sandbox KMS key
mark-r-bjss Apr 2, 2025
1a81080
CCM-8897: create acct level shared sandbox KMS key
mark-r-bjss Apr 3, 2025
7acff5b
CCM-8897: merge in sandbox kms
mark-r-bjss Apr 3, 2025
d4855a4
CCM-8897: jwks key rotation WIP
mark-r-bjss Apr 3, 2025
6bd3767
CCM-8897: add to acct outputs
mark-r-bjss Apr 4, 2025
a9bf2bd
CCM-8897: merge
mark-r-bjss Apr 4, 2025
d1fd25d
CCM-8897: add to acct outputs
mark-r-bjss Apr 4, 2025
7a9e866
CCM-8897: merge
mark-r-bjss Apr 4, 2025
4c3c41f
CCM-8897: jwks key rotation WIP
mark-r-bjss Apr 7, 2025
e387c42
CCM-8897: jwks key rotation WIP
mark-r-bjss Apr 15, 2025
b9235e4
CCM-8897: merge
mark-r-bjss Apr 15, 2025
99820ca
CCM-8897: jwks key rotation WIP
mark-r-bjss Apr 16, 2025
bf78a87
CCM-8897: merge
mark-r-bjss Apr 16, 2025
3745bb2
CCM-8897: unit tests
mark-r-bjss Apr 23, 2025
3cb945a
CCM-8897: merge
mark-r-bjss Apr 23, 2025
d10f284
CCM-8897: unit tests
mark-r-bjss Apr 23, 2025
72499d8
CCM-8897: unit tests
mark-r-bjss Apr 23, 2025
60e03e1
CCM-8897: file format
mark-r-bjss Apr 23, 2025
218ac84
CCM-8897: linting
mark-r-bjss Apr 24, 2025
a2cf743
CCM-8897: unit tests
mark-r-bjss Apr 24, 2025
21e2b0e
CCM-8897: unit tests
mark-r-bjss Apr 24, 2025
25b97bd
CCM-8897: linting
mark-r-bjss Apr 24, 2025
b2de9c2
CCM-8897: unit tests
mark-r-bjss Apr 24, 2025
847a914
CCM-8897: unit tests
mark-r-bjss Apr 24, 2025
2b35829
CCM-8897: unit tests
mark-r-bjss Apr 25, 2025
638accd
CCM-8897: unit tests
mark-r-bjss Apr 28, 2025
d164a80
CCM-8897: unit tests
mark-r-bjss Apr 28, 2025
ba8a9b6
CCM-8897: pipeline debugging
mark-r-bjss Apr 28, 2025
2a0b320
CCM-8897: remove debug logging
mark-r-bjss Apr 29, 2025
1d3bdab
CCM-8897: fix
mark-r-bjss Apr 29, 2025
ea4c469
CCM-8897: self review
mark-r-bjss Apr 29, 2025
8a52d28
CCM-8897: review
mark-r-bjss Apr 29, 2025
1df1ffc
CCM-8897: review
mark-r-bjss Apr 29, 2025
3f51a6e
CCM-8897: review
mark-r-bjss Apr 30, 2025
57f6354
CCM-8897: review
mark-r-bjss Apr 30, 2025
847426f
CCM-8897: fix
mark-r-bjss Apr 30, 2025
cf2645a
CCM-9554: key rotation tests - wip
mark-r-bjss May 2, 2025
558ce9d
CCM-9554: key rotation tests - wip
mark-r-bjss May 6, 2025
062a72b
CCM-9554: fix s3 permissions for public keys
mark-r-bjss May 7, 2025
b3e96e1
CCM-9554: merge
mark-r-bjss May 9, 2025
e4cb4ff
CCM-9551: merge
mark-r-bjss May 9, 2025
80ac6f5
CCM-9551: merge fix to update s3 bucket policy
mark-r-bjss May 9, 2025
7bf369f
CCM-9554: merge
mark-r-bjss May 9, 2025
646467f
CCM-9554: key rotation tests - wip
mark-r-bjss May 12, 2025
75ef51a
CCM-9554: merge
mark-r-bjss May 16, 2025
6e89321
CCM-9554: linting
mark-r-bjss May 16, 2025
8ebf2ef
CCM-9554: linting
mark-r-bjss May 16, 2025
ced8e80
CCM-9554: linting
mark-r-bjss May 16, 2025
11fa4e6
CCM-9554: update tests
mark-r-bjss May 16, 2025
dc62e4d
CCM-9554: update tests
mark-r-bjss May 19, 2025
53b0f5a
CCM-9554: update tests
mark-r-bjss May 20, 2025
dec53c9
CCM-9554: merge
mark-r-bjss May 20, 2025
2b932c8
CCM-9554: update vuln scanner
mark-r-bjss May 21, 2025
b4f73d6
CCM-9554: merge
mark-r-bjss May 21, 2025
3f93785
CCM-9554: support internal repo override
mark-r-bjss May 22, 2025
c853a10
CCM-9554: test internal repo changes
mark-r-bjss May 22, 2025
fc233d6
CCM-9554: revert test internal repo changes
mark-r-bjss May 22, 2025
8c847d3
CCM-9554: merge
mark-r-bjss May 22, 2025
4dc3453
CCM-9554: dynamic tests WIP
mark-r-bjss May 23, 2025
1947e8e
CCM-9554: dynamic tests WIP
mark-r-bjss May 23, 2025
c083ce9
CCM-9554: dynamic tests WIP
mark-r-bjss May 23, 2025
0bec5bb
CCM-9554: dynamic tests WIP
mark-r-bjss May 23, 2025
72af503
CCM-9554: merge
mark-r-bjss May 27, 2025
94d3784
CCM-9554: merge
mark-r-bjss May 27, 2025
a2a3714
CCM-9554: merge
mark-r-bjss May 27, 2025
accd020
CCM-9554: dynamic tests WIP
mark-r-bjss May 27, 2025
69e5297
CCM-9554: dynamic tests
mark-r-bjss May 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .github/actions/acceptance-tests/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,14 @@ runs:
uses: actions/upload-artifact@v4
with:
name: UI test report
path: "tests/test-team/playwright-report"
path: "tests/test-team/playwright-report-component-tests"

- name: Archive backend test results
if: ${{ inputs.testType == 'backend' }}
uses: actions/upload-artifact@v4
with:
name: Backend test report
path: "tests/test-team/playwright-report-backend-tests"

- name: Archive accessibility results
if: ${{ inputs.testType == 'accessibility' }}
Expand Down
3 changes: 3 additions & 0 deletions .github/actions/test-types.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[
"backend"
]
6 changes: 5 additions & 1 deletion .github/workflows/dispatch_internal_repo_workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ on:
type: string
description: The Terraform action to run
default: ""
internalRef:
type: string
description: Internal repo reference (branch or tag)
default: "feature/CCM-9554_optional-backend-tests"

permissions:
id-token: write
Expand Down Expand Up @@ -62,7 +66,7 @@ jobs:
--arg targetComponent ${{ inputs.targetComponent }} \
--arg terraformAction "${{ inputs.terraformAction }}" \
'{
"ref": "main",
"ref": "${{ inputs.internalRef }}",
"inputs": (
(if $infraRepoName != "" then { "infraRepoName": $infraRepoName } else {} end) +
(if $terraformAction != "" then { "terraformAction": $terraformAction } else {} end) +
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ next-env.d.ts
# playwright
tests/test-team/test-results/
tests/test-team/playwright-report/
tests/test-team/playwright-report-component-tests/
tests/test-team/playwright-report-backend-tests/
tests/test-team/blob-report/
tests/test-team/playwright/.cache/
*.webm
Expand Down
20 changes: 20 additions & 0 deletions infrastructure/terraform/components/sandbox/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,23 @@ output "csrf_secret" {

sensitive = true
}

output "name_tag" {
value = local.default_tags["Name"]
}

output "group_tag" {
value = local.default_tags["Group"]
}

output "key_directory_ssm_parameter_name" {
value = module.public_signing_keys.key_directory_ssm_parameter_name
}

output "key_rotation_lambda_name" {
value = module.public_signing_keys.key_rotation_lambda_name
}

output "public_keys_s3_bucket_name" {
value = module.public_signing_keys.public_keys_s3_bucket_name
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ module "s3bucket_public_signing_keys" {
]

policy_documents = [
data.aws_iam_policy_document.s3bucket_public_keys.json
data.aws_iam_policy_document.bucket_policy_public_signing_keys.json
]

public_access = {
Expand All @@ -55,79 +55,6 @@ module "s3bucket_public_signing_keys" {
}
}

data "aws_iam_policy_document" "s3bucket_public_keys" {
statement {
sid = "DontAllowNonSecureConnection"
effect = "Deny"

actions = [
"s3:*",
]

resources = [
module.s3bucket_public_signing_keys.arn,
"${module.s3bucket_public_signing_keys.arn}/*",
]

principals {
type = "AWS"

identifiers = [
"*",
]
}

condition {
test = "Bool"
variable = "aws:SecureTransport"

values = [
"false",
]
}
}

statement {
sid = "AllowManagedAccountsToList"
effect = "Allow"

actions = [
"s3:ListBucket",
]

resources = [
module.s3bucket_public_signing_keys.arn,
]

principals {
type = "AWS"
identifiers = [
"arn:aws:iam::${var.aws_account_id}:root"
]
}
}

statement {
sid = "AllowManagedAccountsToGet"
effect = "Allow"

actions = [
"s3:GetObject",
]

resources = [
"${module.s3bucket_public_signing_keys.arn}/*",
]

principals {
type = "AWS"
identifiers = [
"arn:aws:iam::${var.aws_account_id}:root"
]
}
}
}

resource "aws_s3_bucket_cors_configuration" "public_public_keys" {
bucket = module.s3bucket_public_signing_keys.bucket

Expand Down
11 changes: 11 additions & 0 deletions infrastructure/terraform/modules/public-signing-keys/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
output "key_directory_ssm_parameter_name" {
value = local.ssm_key_directory_name
}

output "key_rotation_lambda_name" {
value = module.lambda_jwks_key_rotation.function_name
}

output "public_keys_s3_bucket_name" {
value = module.s3bucket_public_signing_keys.bucket
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
resource "aws_s3_bucket_policy" "public_signing_keys" {
bucket = module.s3bucket_public_signing_keys.id
policy = data.aws_iam_policy_document.bucket_policy_public_signing_keys.json
}

data "aws_iam_policy_document" "bucket_policy_public_signing_keys" {
statement {
sid = "AllowManagedAccountsToRead"
actions = ["s3:GetObject", "s3:ListBucket"]
resources = [
module.s3bucket_public_signing_keys.arn,
Expand All @@ -20,6 +16,7 @@ data "aws_iam_policy_document" "bucket_policy_public_signing_keys" {
dynamic "statement" {
for_each = var.deploy_cdn ? [1] : []
content {
sid = "AllowCDNAccess"
actions = ["s3:GetObject", "s3:ListBucket"]
resources = [
module.s3bucket_public_signing_keys.arn,
Expand All @@ -34,6 +31,7 @@ data "aws_iam_policy_document" "bucket_policy_public_signing_keys" {
}

statement {
sid = "DontAllowNonSecureConnection"
effect = "Deny"
actions = ["s3:*"]
resources = [
Expand Down
38 changes: 38 additions & 0 deletions lambdas/jwks-key-rotation/src/__tests__/handler.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { handler } from '@/src/handler';
import { Context, EventBridgeEvent, Callback } from 'aws-lambda';
import {
filterKeyDirectoryToActiveKeys,
getKeyDirectory,
SigningKeyDirectory,
writeKeyDirectory,
Expand All @@ -12,6 +13,7 @@ import { deleteKey } from '@/src/utils/aws/kms-util';
jest.mock('@/src/utils/key-directory-repository', () => ({
...jest.requireActual('@/src/utils/key-directory-repository'),
getKeyDirectory: jest.fn(),
filterKeyDirectoryToActiveKeys: jest.fn(),
writeKeyDirectory: jest.fn(),
}));
jest.mock('@/src/utils/key-util');
Expand All @@ -30,13 +32,19 @@ describe('handler', () => {
const todayFormatted = new Date().toISOString().split('T')[0];

const mockedGetKeyDirectory = jest.mocked(getKeyDirectory);
const mockedFilterKeyDirectoryToActiveKeys = jest.mocked(
filterKeyDirectoryToActiveKeys
);
const mockedGenerateKey = jest.mocked(generateKey);
const mockedGetPublicKey = jest.mocked(getPublicKey);
const mockedWriteKeyDirectory = jest.mocked(writeKeyDirectory);

mockedGetKeyDirectory.mockImplementation(() =>
Promise.resolve(mockKeyDirectory)
);
mockedFilterKeyDirectoryToActiveKeys.mockImplementation(() =>
Promise.resolve(mockKeyDirectory)
);
mockedGenerateKey.mockImplementation(() =>
Promise.resolve('new-test-key-id')
);
Expand All @@ -48,6 +56,9 @@ describe('handler', () => {
await handler(mockEvent, mockContext, mockCallback);

// assert
expect(mockedFilterKeyDirectoryToActiveKeys).toHaveBeenCalledWith(
mockKeyDirectory
);
expect(mockedGenerateKey).toHaveBeenCalled();
expect(updateJwksFile).toHaveBeenCalledWith([
{ keyId: 'new-test-key-id', publicKey: mockPublicKey },
Expand Down Expand Up @@ -78,13 +89,19 @@ describe('handler', () => {
const mockPublicKey = Uint8Array.from([1, 2, 3]);

const mockedGetKeyDirectory = jest.mocked(getKeyDirectory);
const mockedFilterKeyDirectoryToActiveKeys = jest.mocked(
filterKeyDirectoryToActiveKeys
);
const mockedGenerateKey = jest.mocked(generateKey);
const mockedGetPublicKey = jest.mocked(getPublicKey);
const mockedWriteKeyDirectory = jest.mocked(writeKeyDirectory);

mockedGetKeyDirectory.mockImplementation(() =>
Promise.resolve(mockKeyDirectory)
);
mockedFilterKeyDirectoryToActiveKeys.mockImplementation(() =>
Promise.resolve(mockKeyDirectory)
);
mockedGenerateKey.mockImplementation(() =>
Promise.resolve('new-test-key-id')
);
Expand All @@ -96,6 +113,9 @@ describe('handler', () => {
await handler(mockEvent, mockContext, mockCallback);

// assert
expect(mockedFilterKeyDirectoryToActiveKeys).toHaveBeenCalledWith(
mockKeyDirectory
);
expect(mockedGenerateKey).toHaveBeenCalled();
expect(updateJwksFile).toHaveBeenCalledWith([
{
Expand Down Expand Up @@ -146,13 +166,19 @@ describe('handler', () => {
const mockPublicKey = Uint8Array.from([1, 2, 3]);

const mockedGetKeyDirectory = jest.mocked(getKeyDirectory);
const mockedFilterKeyDirectoryToActiveKeys = jest.mocked(
filterKeyDirectoryToActiveKeys
);
const mockedGenerateKey = jest.mocked(generateKey);
const mockedGetPublicKey = jest.mocked(getPublicKey);
const mockedWriteKeyDirectory = jest.mocked(writeKeyDirectory);

mockedGetKeyDirectory.mockImplementation(() =>
Promise.resolve(mockKeyDirectory)
);
mockedFilterKeyDirectoryToActiveKeys.mockImplementation(() =>
Promise.resolve(mockKeyDirectory)
);
mockedGenerateKey.mockImplementation(() =>
Promise.resolve('new-test-key-id')
);
Expand All @@ -164,6 +190,9 @@ describe('handler', () => {
await handler(mockEvent, mockContext, mockCallback);

// assert
expect(mockedFilterKeyDirectoryToActiveKeys).toHaveBeenCalledWith(
mockKeyDirectory
);
expect(mockedGenerateKey).toHaveBeenCalled();
expect(updateJwksFile).toHaveBeenCalledWith([
{
Expand Down Expand Up @@ -208,13 +237,19 @@ describe('handler', () => {
const mockPublicKey = Uint8Array.from([1, 2, 3]);

const mockedGetKeyDirectory = jest.mocked(getKeyDirectory);
const mockedFilterKeyDirectoryToActiveKeys = jest.mocked(
filterKeyDirectoryToActiveKeys
);
const mockedGenerateKey = jest.mocked(generateKey);
const mockedGetPublicKey = jest.mocked(getPublicKey);
const mockedWriteKeyDirectory = jest.mocked(writeKeyDirectory);

mockedGetKeyDirectory.mockImplementation(() =>
Promise.resolve(mockKeyDirectory)
);
mockedFilterKeyDirectoryToActiveKeys.mockImplementation(() =>
Promise.resolve(mockKeyDirectory)
);
mockedGenerateKey.mockImplementation(() =>
Promise.resolve('new-test-key-id')
);
Expand All @@ -226,6 +261,9 @@ describe('handler', () => {
await handler(mockEvent, mockContext, mockCallback);

// assert
expect(mockedFilterKeyDirectoryToActiveKeys).toHaveBeenCalledWith(
mockKeyDirectory
);
expect(mockedGenerateKey).toHaveBeenCalled();
expect(updateJwksFile).toHaveBeenCalledWith([
{
Expand Down
Loading