Skip to content
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
62a9015
[PRMP-1444] create user restrictions table
steph-torres-nhs Feb 16, 2026
0ea6364
[PRMP-1444] format
steph-torres-nhs Feb 16, 2026
7f99fe6
[PRMP-1444] fix typo
steph-torres-nhs Feb 16, 2026
380a9a9
[PRMP-1444] add status and creator to restrictions table
steph-torres-nhs Feb 16, 2026
70744db
[PRMP-1444] format
steph-torres-nhs Feb 16, 2026
8e67a9a
[PRMP-1444] add last updated attribute
steph-torres-nhs Feb 16, 2026
c5d6666
[PRMP-1444] removed unindexed attributes
steph-torres-nhs Feb 16, 2026
469b5ed
[PRMP-1445] add user restriction gateways
steph-torres-nhs Feb 16, 2026
daadf27
[PRPM-1445] add api dependencies
steph-torres-nhs Feb 16, 2026
7f22188
[PRMP-1445] add files
steph-torres-nhs Feb 16, 2026
d391d22
[PRMP-1445] add delete user restriction lambda infra
steph-torres-nhs Feb 16, 2026
8da779e
[PRMP-1445] add search user restrictions lambda infra
steph-torres-nhs Feb 16, 2026
015e35e
[PRMP-1445] create search user info lambda infra
steph-torres-nhs Feb 16, 2026
7c2bbd0
[PRMP-1445] remove cycle
steph-torres-nhs Feb 16, 2026
ea2a6f7
[PRMP-1445] add missing id
steph-torres-nhs Feb 16, 2026
570ca68
[PRMP-1445] fix typos
steph-torres-nhs Feb 17, 2026
c3195e8
[PRMP-1445] fix typo, remove used gateway
steph-torres-nhs Feb 17, 2026
fe57e41
Merge branch 'main' into PRMP-1445
steph-torres-nhs Feb 17, 2026
ca966a6
Merge branch 'main' into PRMP-1444
steph-torres-nhs Feb 18, 2026
c8f4d86
[PRMP-1444] changed ods code attribute to custodian
steph-torres-nhs Feb 18, 2026
3778a57
[PRMP-1444] amend attributes and indexes
steph-torres-nhs Feb 18, 2026
dc9dba8
Merge branch 'PRMP-1444' into PRMP-1445
steph-torres-nhs Feb 18, 2026
5f34934
[PRMP-1444] add custodian index order by created
steph-torres-nhs Feb 18, 2026
ce644ce
[PRMP-1444] remove unnecessary attributes and indexes
steph-torres-nhs Feb 19, 2026
883ac96
Merge branch 'PRMP-1444' into PRMP-1445
steph-torres-nhs Feb 19, 2026
ef133d1
[PRMP-1445] adjust permissions
steph-torres-nhs Feb 19, 2026
95e4c98
[PRMP-1444] address PR comments
steph-torres-nhs Feb 19, 2026
a6a501d
Merge branch 'PRMP-1444' into PRMP-1445
steph-torres-nhs Feb 19, 2026
ac0e641
Merge branch 'main' into PRMP-1445
steph-torres-nhs Feb 19, 2026
bac845c
Merge branch 'main' into PRMP-1445
steph-torres-nhs Feb 23, 2026
22ad842
[PRMP-1445] reorder dependencies
steph-torres-nhs Feb 23, 2026
f8012a6
Merge branch 'PRMP-1445' of https://github.com/nhsconnect/national-do…
steph-torres-nhs Feb 23, 2026
09b3b12
Merge branch 'main' into PRMP-1445
steph-torres-nhs Feb 23, 2026
c400655
[PRMP-1445] update names
steph-torres-nhs Feb 23, 2026
3f3e881
Merge branch 'PRMP-1445' of https://github.com/nhsconnect/national-do…
steph-torres-nhs Feb 23, 2026
665cdf9
Merge branch 'main' into PRMP-1445
steph-torres-nhs Feb 23, 2026
0f7002d
Merge branch 'main' into PRMP-1445
steph-torres-nhs Feb 24, 2026
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
28 changes: 17 additions & 11 deletions infrastructure/api.tf
Original file line number Diff line number Diff line change
Expand Up @@ -52,43 +52,49 @@ resource "aws_api_gateway_deployment" "ndr_api_deploy" {
module.create-token-gateway,
module.create-token-lambda,
module.delete-doc-ref-gateway,
module.delete-document-references-fhir-lambda,
module.delete-doc-ref-lambda,
module.delete-document-references-fhir-lambda,
module.delete_user_restriction_lambda,
module.document-manifest-job-gateway,
module.document-manifest-job-lambda,
module.document_reference_gateway,
module.document-status-check-gateway,
module.document-status-check-lambda,
module.feature-flags-gateway,
module.feature-flags-lambda,
module.fhir_document_reference_gateway,
module.get-doc-fhir-lambda,
module.get_document_review_lambda,
module.get-doc-ref-lambda,
module.get_document_review_lambda,
module.get-report-by-ods-gateway,
module.get-report-by-ods-lambda,
module.lloyd-george-stitch-gateway,
module.lloyd-george-stitch-lambda,
module.logout-gateway,
module.logout_lambda,
module.patch_document_review_lambda,
module.post-document-references-fhir-lambda,
module.post_document_review_lambda,
module.post_user_restriction_lambda,
module.review_document_status_gateway,
module.review-document-status-check-lambda,
module.review_document_version_gateway,
module.search-document-references-gateway,
module.search-document-references-lambda,
module.search_document_review_lambda,
module.search-patient-details-gateway,
module.search-patient-details-lambda,
module.search_user_information_lambda,
module.search_user_restriction_lambda,
module.send-feedback-gateway,
module.send-feedback-lambda,
module.review_document_version_gateway,
module.review_document_status_gateway,
module.review-document-status-check-lambda,
module.update-doc-ref-lambda,
module.update-upload-state-gateway,
module.update-upload-state-lambda,
module.document-status-check-gateway,
module.document-status-check-lambda,
module.post-document-references-fhir-lambda,
module.post_document_review_lambda,
module.patch_document_review_lambda,
module.user_restrictions_gateway,
module.user_restrictions_user_search_gateway,
module.virus_scan_result_gateway,
module.virus_scan_result_lambda
module.virus_scan_result_lambda,
]

lifecycle {
Expand Down
55 changes: 55 additions & 0 deletions infrastructure/dynamo_db.tf
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,61 @@ module "bulk_upload_contact_lookup_table" {
},
]

environment = var.environment
owner = var.owner
}

module "user_restriction_table" {
source = "./modules/dynamo_db"
table_name = var.user_restrictions_table_name
hash_key = "ID"
deletion_protection_enabled = var.deletion_protection_enabled
point_in_time_recovery_enabled = !local.is_sandbox

attributes = [
{
name = "ID"
type = "S"
},
{
name = "RestrictedSmartcard"
type = "S"
},
{
name = "NhsNumber"
type = "S"
},
{
name = "Custodian"
type = "S"
},
{
name = "Created"
type = "N"
},
]

global_secondary_indexes = [
{
name = "RestrictedSmartcardIndex"
hash_key = "RestrictedSmartcard"
range_key = "Created"
Comment thread
steph-torres-nhs marked this conversation as resolved.
projection_type = "ALL"
},
{
name = "NhsNumberIndex"
hash_key = "NhsNumber"
range_key = "Created"
projection_type = "ALL"
},
{
name = "CustodianIndex"
hash_key = "Custodian"
range_key = "Created"
projection_type = "ALL"
}
]

environment = var.environment
owner = var.owner
}
39 changes: 39 additions & 0 deletions infrastructure/gateway-user-restrictions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module "user_restrictions_gateway" {
source = "./modules/gateway"
api_gateway_id = aws_api_gateway_rest_api.ndr_doc_store_api.id
parent_id = aws_api_gateway_rest_api.ndr_doc_store_api.root_resource_id
http_methods = ["GET", "POST"]
authorization = "CUSTOM"
gateway_path = "UserRestriction"
authorizer_id = aws_api_gateway_authorizer.repo_authoriser.id
require_credentials = true
origin = contains(["prod"], terraform.workspace) ? "'https://${var.domain}'" : "'https://${terraform.workspace}.${var.domain}'"
}

module "user_restriction_id_gateway" {
source = "./modules/gateway"
api_gateway_id = aws_api_gateway_rest_api.ndr_doc_store_api.id
parent_id = module.user_restrictions_gateway.gateway_resource_id
http_methods = ["DELETE"]
gateway_path = "{id}"
authorization = "CUSTOM"
authorizer_id = aws_api_gateway_authorizer.repo_authoriser.id
require_credentials = true
origin = contains(["prod"], terraform.workspace) ? "'https://${var.domain}'" : "'https://${terraform.workspace}.${var.domain}'"

request_parameters = {
"method.request.path.id" = true
}
}

module "user_restrictions_user_search_gateway" {
source = "./modules/gateway"
api_gateway_id = aws_api_gateway_rest_api.ndr_doc_store_api.id
parent_id = module.user_restrictions_gateway.gateway_resource_id
http_methods = ["GET"]
gateway_path = "SearchUser"
authorization = "CUSTOM"
authorizer_id = aws_api_gateway_authorizer.repo_authoriser.id
require_credentials = true
origin = contains(["prod"], terraform.workspace) ? "'https://${var.domain}'" : "'https://${terraform.workspace}.${var.domain}'"
}
66 changes: 66 additions & 0 deletions infrastructure/lambda-delete-user-restriction.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
module "delete_user_restriction_lambda" {
source = "./modules/lambda"
name = "DeleteUserRestriction"
handler = "handlers.delete_user_restriction_handler.lambda_handler"
iam_role_policy_documents = [
module.ndr-app-config.app_config_policy,
aws_iam_policy.ssm_access_policy.policy,
module.user_restriction_table.dynamodb_write_policy_document
]
kms_deletion_window = var.kms_deletion_window
rest_api_id = aws_api_gateway_rest_api.ndr_doc_store_api.id
resource_id = module.user_restriction_id_gateway.gateway_resource_id
http_methods = ["DELETE"]
api_execution_arn = aws_api_gateway_rest_api.ndr_doc_store_api.execution_arn
lambda_environment_variables = {
APPCONFIG_APPLICATION = module.ndr-app-config.app_config_application_id
APPCONFIG_ENVIRONMENT = module.ndr-app-config.app_config_environment_id
APPCONFIG_CONFIGURATION = module.ndr-app-config.app_config_configuration_profile_id
WORKSPACE = terraform.workspace
RESTRICTIONS_TABLE_NAME = module.user_restriction_table.table_name
}

depends_on = [
aws_api_gateway_rest_api.ndr_doc_store_api,
module.user_restriction_id_gateway
]
}

module "delete_user_restriction_lambda_alarms" {
source = "./modules/lambda_alarms"
lambda_function_name = module.delete_user_restriction_lambda.function_name
lambda_timeout = module.delete_user_restriction_lambda.timeout
lambda_name = module.delete_user_restriction_lambda.function_name
namespace = "AWS/Lambda"
alarm_actions = [module.delete_user_restriction_lambda_alarm_topic.arn]
ok_actions = [module.delete_user_restriction_lambda_alarm_topic.arn]
}

module "delete_user_restriction_lambda_alarm_topic" {
source = "./modules/sns"
sns_encryption_key_id = module.sns_encryption_key.id
topic_name = "delete-user-restriction-lambda-alarm-topic"
topic_protocol = "email"
is_topic_endpoint_list = true
topic_endpoint_list = local.is_sandbox ? [] : nonsensitive(split(",", data.aws_ssm_parameter.cloud_security_notification_email_list.value))
delivery_policy = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Effect" : "Allow",
"Principal" : {
"Service" : "cloudwatch.amazonaws.com"
},
"Action" : [
"SNS:Publish",
],
"Condition" : {
"ArnLike" : {
"aws:SourceArn" : "arn:aws:cloudwatch:eu-west-2:${data.aws_caller_identity.current.account_id}:alarm:*"
}
}
"Resource" : "*"
}
]
})
}
66 changes: 66 additions & 0 deletions infrastructure/lambda-post-user-restriction.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
module "post_user_restriction_lambda" {
source = "./modules/lambda"
name = "CreateUserRestriction"
handler = "handlers.create_user_restriction_handler.lambda_handler"
iam_role_policy_documents = [
module.ndr-app-config.app_config_policy,
aws_iam_policy.ssm_access_policy.policy,
module.user_restriction_table.dynamodb_write_policy_document
]
kms_deletion_window = var.kms_deletion_window
rest_api_id = aws_api_gateway_rest_api.ndr_doc_store_api.id
resource_id = module.user_restrictions_gateway.gateway_resource_id
http_methods = ["POST"]
api_execution_arn = aws_api_gateway_rest_api.ndr_doc_store_api.execution_arn
lambda_environment_variables = {
APPCONFIG_APPLICATION = module.ndr-app-config.app_config_application_id
APPCONFIG_ENVIRONMENT = module.ndr-app-config.app_config_environment_id
APPCONFIG_CONFIGURATION = module.ndr-app-config.app_config_configuration_profile_id
WORKSPACE = terraform.workspace
RESTRICTIONS_TABLE_NAME = module.user_restriction_table.table_name
}

depends_on = [
aws_api_gateway_rest_api.ndr_doc_store_api,
module.user_restrictions_gateway
]
}

module "post_user_restriction_lambda_alarms" {
source = "./modules/lambda_alarms"
lambda_function_name = module.post_user_restriction_lambda.function_name
lambda_timeout = module.post_user_restriction_lambda.timeout
lambda_name = module.post_user_restriction_lambda.function_name
namespace = "AWS/Lambda"
alarm_actions = [module.post_user_restriction_lambda_alarm_topic.arn]
ok_actions = [module.post_user_restriction_lambda_alarm_topic.arn]
}

module "post_user_restriction_lambda_alarm_topic" {
source = "./modules/sns"
sns_encryption_key_id = module.sns_encryption_key.id
topic_name = "post-user-restriction-lambda-alarm-topic"
topic_protocol = "email"
is_topic_endpoint_list = true
topic_endpoint_list = local.is_sandbox ? [] : nonsensitive(split(",", data.aws_ssm_parameter.cloud_security_notification_email_list.value))
delivery_policy = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Effect" : "Allow",
"Principal" : {
"Service" : "cloudwatch.amazonaws.com"
},
"Action" : [
"SNS:Publish",
],
"Condition" : {
"ArnLike" : {
"aws:SourceArn" : "arn:aws:cloudwatch:eu-west-2:${data.aws_caller_identity.current.account_id}:alarm:*"
}
}
"Resource" : "*"
}
]
})
}
64 changes: 64 additions & 0 deletions infrastructure/lambda-search-user-information.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
module "search_user_information_lambda" {
source = "./modules/lambda"
name = "SearchUserInformation"
handler = "handlers.search_user_information_handler.lambda_handler"
iam_role_policy_documents = [
module.ndr-app-config.app_config_policy,
aws_iam_policy.ssm_access_policy.policy,
]
kms_deletion_window = var.kms_deletion_window
rest_api_id = aws_api_gateway_rest_api.ndr_doc_store_api.id
resource_id = module.user_restrictions_user_search_gateway.gateway_resource_id
http_methods = ["GET"]
api_execution_arn = aws_api_gateway_rest_api.ndr_doc_store_api.execution_arn
lambda_environment_variables = {
APPCONFIG_APPLICATION = module.ndr-app-config.app_config_application_id
APPCONFIG_ENVIRONMENT = module.ndr-app-config.app_config_environment_id
APPCONFIG_CONFIGURATION = module.ndr-app-config.app_config_configuration_profile_id
WORKSPACE = terraform.workspace
}

depends_on = [
aws_api_gateway_rest_api.ndr_doc_store_api,
module.user_restrictions_user_search_gateway
]
}

module "search_user_information_lambda_alarms" {
source = "./modules/lambda_alarms"
lambda_function_name = module.search_user_information_lambda.function_name
lambda_timeout = module.search_user_information_lambda.timeout
lambda_name = module.search_user_information_lambda.function_name
namespace = "AWS/Lambda"
alarm_actions = [module.search_user_information_lambda_alarm_topic.arn]
ok_actions = [module.search_user_information_lambda_alarm_topic.arn]
}

module "search_user_information_lambda_alarm_topic" {
source = "./modules/sns"
sns_encryption_key_id = module.sns_encryption_key.id
topic_name = "search-user-information-lambda-alarm-topic"
topic_protocol = "email"
is_topic_endpoint_list = true
topic_endpoint_list = local.is_sandbox ? [] : nonsensitive(split(",", data.aws_ssm_parameter.cloud_security_notification_email_list.value))
delivery_policy = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Effect" : "Allow",
"Principal" : {
"Service" : "cloudwatch.amazonaws.com"
},
"Action" : [
"SNS:Publish",
],
"Condition" : {
"ArnLike" : {
"aws:SourceArn" : "arn:aws:cloudwatch:eu-west-2:${data.aws_caller_identity.current.account_id}:alarm:*"
}
}
"Resource" : "*"
}
]
})
}
Loading