Skip to content

Commit 143778c

Browse files
authored
Merge pull request #85 from zama-ai/fred/feat/add-mpc-backup-key-module
feat: add mpc-backup-vault module
2 parents ed463c9 + 4519ff7 commit 143778c

File tree

13 files changed

+507
-21
lines changed

13 files changed

+507
-21
lines changed

modules/mpc-backup-key/README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<!-- BEGIN_TF_DOCS -->
2+
## Requirements
3+
4+
| Name | Version |
5+
|------|---------|
6+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.10 |
7+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
8+
| <a name="requirement_random"></a> [random](#requirement\_random) | >= 3.1 |
9+
10+
## Providers
11+
12+
| Name | Version |
13+
|------|---------|
14+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
15+
16+
## Modules
17+
18+
No modules.
19+
20+
## Resources
21+
22+
| Name | Type |
23+
|------|------|
24+
| [aws_kms_alias.this_backup](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource |
25+
| [aws_kms_key.this_backup](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
26+
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
27+
28+
## Inputs
29+
30+
| Name | Description | Type | Default | Required |
31+
|------|-------------|------|---------|:--------:|
32+
| <a name="input_mpc_party_cross_account_iam_role_arn"></a> [mpc\_party\_cross\_account\_iam\_role\_arn](#input\_mpc\_party\_cross\_account\_iam\_role\_arn) | ARN of cross-account IAM role allowed for usage of KMS key | `string` | `null` | no |
33+
| <a name="input_mpc_party_kms_alias"></a> [mpc\_party\_kms\_alias](#input\_mpc\_party\_kms\_alias) | Alias for the KMS key | `string` | `null` | no |
34+
| <a name="input_mpc_party_kms_backup_description"></a> [mpc\_party\_kms\_backup\_description](#input\_mpc\_party\_kms\_backup\_description) | Description of KMS Key | `string` | `"Asymmetric KMS key backup for MPC Party"` | no |
35+
| <a name="input_mpc_party_kms_backup_vault_customer_master_key_spec"></a> [mpc\_party\_kms\_backup\_vault\_customer\_master\_key\_spec](#input\_mpc\_party\_kms\_backup\_vault\_customer\_master\_key\_spec) | Key spec for the backup vault | `string` | `"ASYMMETRIC_DEFAULT"` | no |
36+
| <a name="input_mpc_party_kms_backup_vault_key_usage"></a> [mpc\_party\_kms\_backup\_vault\_key\_usage](#input\_mpc\_party\_kms\_backup\_vault\_key\_usage) | Key usage for the backup vault | `string` | `"ENCRYPT_DECRYPT"` | no |
37+
| <a name="input_mpc_party_kms_deletion_window_in_days"></a> [mpc\_party\_kms\_deletion\_window\_in\_days](#input\_mpc\_party\_kms\_deletion\_window\_in\_days) | Deletion window in days for KMS key | `number` | `30` | no |
38+
| <a name="input_mpc_party_kms_image_attestation_sha"></a> [mpc\_party\_kms\_image\_attestation\_sha](#input\_mpc\_party\_kms\_image\_attestation\_sha) | Attestation SHA for KMS image | `string` | `null` | no |
39+
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to assign to the resource | `map(string)` | <pre>{<br/> "module": "mpc-party-backup",<br/> "terraform": "true"<br/>}</pre> | no |
40+
41+
## Outputs
42+
43+
No outputs.
44+
<!-- END_TF_DOCS -->

modules/mpc-backup-key/main.tf

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# ************
2+
# Data Sources
3+
# ************
4+
data "aws_caller_identity" "current" {}
5+
6+
# ************
7+
# ASYMMETRIC KMS Key Backup for MPC Party
8+
# ************
9+
resource "aws_kms_key" "this_backup" {
10+
description = var.mpc_party_kms_backup_description
11+
key_usage = var.mpc_party_kms_backup_vault_key_usage
12+
customer_master_key_spec = var.mpc_party_kms_backup_vault_customer_master_key_spec
13+
enable_key_rotation = false
14+
deletion_window_in_days = var.mpc_party_kms_deletion_window_in_days
15+
tags = var.tags
16+
17+
policy = jsonencode({
18+
Version = "2012-10-17"
19+
Statement = [
20+
{
21+
Sid = "Allow access for Key Administrators", # https://docs.aws.amazon.com/kms/latest/developerguide/key-policy-default.html#key-policy-default-allow-administrators
22+
Effect = "Allow",
23+
Principal = {
24+
AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
25+
},
26+
Action = [
27+
"kms:Create*",
28+
"kms:Describe*",
29+
"kms:Enable*",
30+
"kms:List*",
31+
"kms:Put*",
32+
"kms:Update*",
33+
"kms:Revoke*",
34+
"kms:Disable*",
35+
"kms:Get*",
36+
"kms:Delete*",
37+
"kms:TagResource",
38+
"kms:UntagResource",
39+
"kms:ScheduleKeyDeletion",
40+
"kms:CancelKeyDeletion"
41+
],
42+
Resource = "*"
43+
},
44+
{
45+
Effect = "Allow",
46+
Principal = {
47+
AWS = var.mpc_party_cross_account_iam_role_arn
48+
},
49+
Action = [
50+
"kms:GetPublicKey",
51+
],
52+
Resource = "*"
53+
},
54+
{
55+
Effect = "Allow",
56+
Principal = {
57+
AWS = var.mpc_party_cross_account_iam_role_arn
58+
},
59+
Action = [
60+
"kms:Decrypt",
61+
"kms:GenerateDataKey",
62+
],
63+
Resource = "*",
64+
Condition = {
65+
StringEqualsIgnoreCase = {
66+
"kms:RecipientAttestation:ImageSha384" : var.mpc_party_kms_image_attestation_sha
67+
}
68+
}
69+
},
70+
]
71+
})
72+
}
73+
74+
resource "aws_kms_alias" "this_backup" {
75+
name = "${var.mpc_party_kms_alias}-backup"
76+
target_key_id = aws_kms_key.this_backup.key_id
77+
}

modules/mpc-backup-key/outputs.tf

Whitespace-only changes.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# ************
2+
# General variables
3+
# ************
4+
# Tagging
5+
variable "tags" {
6+
type = map(string)
7+
description = "A map of tags to assign to the resource"
8+
default = {
9+
"terraform" = "true"
10+
"module" = "mpc-party-backup"
11+
}
12+
}
13+
14+
# ************
15+
# Variables for usage in main.tf
16+
# ************
17+
18+
variable "mpc_party_cross_account_iam_role_arn" {
19+
type = string
20+
description = "ARN of cross-account IAM role allowed for usage of KMS key"
21+
default = null
22+
}
23+
24+
variable "mpc_party_kms_image_attestation_sha" {
25+
type = string
26+
description = "Attestation SHA for KMS image"
27+
default = null
28+
}
29+
30+
variable "mpc_party_kms_alias" {
31+
type = string
32+
description = "Alias for the KMS key"
33+
default = null
34+
}
35+
36+
variable "mpc_party_kms_deletion_window_in_days" {
37+
type = number
38+
description = "Deletion window in days for KMS key"
39+
default = 30
40+
}
41+
42+
variable "mpc_party_kms_backup_description" {
43+
type = string
44+
description = "Description of KMS Key"
45+
default = "Asymmetric KMS key backup for MPC Party"
46+
}
47+
48+
variable "mpc_party_kms_backup_vault_key_usage" {
49+
type = string
50+
description = "Key usage for the backup vault"
51+
default = "ENCRYPT_DECRYPT"
52+
}
53+
54+
variable "mpc_party_kms_backup_vault_customer_master_key_spec" {
55+
type = string
56+
description = "Key spec for the backup vault"
57+
default = "ASYMMETRIC_DEFAULT"
58+
}

modules/mpc-backup-key/versions.tf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
terraform {
2+
required_version = ">= 1.10"
3+
4+
required_providers {
5+
aws = {
6+
source = "hashicorp/aws"
7+
version = ">= 6.0"
8+
}
9+
random = {
10+
source = "hashicorp/random"
11+
version = ">= 3.1"
12+
}
13+
}
14+
}

modules/mpc-backup-vault/README.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# MPC Key backup modules\
2+
3+
This module is aim to create :
4+
- bucket for backup vault
5+
6+
The kms keys is handled by kms-stack terraform module in infra repo.
7+
8+
<!-- BEGIN_TF_DOCS -->
9+
## Requirements
10+
11+
| Name | Version |
12+
|------|---------|
13+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.10 |
14+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
15+
| <a name="requirement_random"></a> [random](#requirement\_random) | >= 3.1 |
16+
17+
## Providers
18+
19+
| Name | Version |
20+
|------|---------|
21+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
22+
| <a name="provider_random"></a> [random](#provider\_random) | >= 3.1 |
23+
24+
## Modules
25+
26+
No modules.
27+
28+
## Resources
29+
30+
| Name | Type |
31+
|------|------|
32+
| [aws_iam_policy.mpc_aws](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
33+
| [aws_iam_role.mpc_backup_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
34+
| [aws_iam_role_policy_attachment.mpc_backup_attach](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
35+
| [aws_s3_bucket.backup_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |
36+
| [aws_s3_bucket_ownership_controls.backup_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_ownership_controls) | resource |
37+
| [aws_s3_bucket_policy.backup_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource |
38+
| [aws_s3_bucket_public_access_block.backup_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource |
39+
| [aws_s3_bucket_versioning.backup_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource |
40+
| [random_id.mpc_party_suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource |
41+
| [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
42+
43+
## Inputs
44+
45+
| Name | Description | Type | Default | Required |
46+
|------|-------------|------|---------|:--------:|
47+
| <a name="input_bucket_cross_account_id"></a> [bucket\_cross\_account\_id](#input\_bucket\_cross\_account\_id) | ID of the AWS account that can access the backup bucket. | `string` | n/a | yes |
48+
| <a name="input_bucket_prefix"></a> [bucket\_prefix](#input\_bucket\_prefix) | The prefix for the S3 bucket names | `string` | `"mpc-backup-vault"` | no |
49+
| <a name="input_party_name"></a> [party\_name](#input\_party\_name) | The name of the MPC party (used for resource naming and tagging) | `string` | n/a | yes |
50+
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to assign to the resource | `map(string)` | <pre>{<br/> "module": "mpc-party",<br/> "terraform": "true"<br/>}</pre> | no |
51+
| <a name="input_trusted_principal_arns"></a> [trusted\_principal\_arns](#input\_trusted\_principal\_arns) | List of ARNs (users, roles, or root accounts) that can assume the backup role. | `list(string)` | `[]` | no |
52+
53+
## Outputs
54+
55+
| Name | Description |
56+
|------|-------------|
57+
| <a name="output_bucket_arn"></a> [bucket\_arn](#output\_bucket\_arn) | The ARN of the created S3 bucket |
58+
| <a name="output_bucket_name"></a> [bucket\_name](#output\_bucket\_name) | The name of the created S3 bucket |
59+
| <a name="output_role_arn"></a> [role\_arn](#output\_role\_arn) | The ARN of the IAM role created for accessing the bucket |
60+
| <a name="output_role_name"></a> [role\_name](#output\_role\_name) | The name of the IAM role created for accessing the bucket |
61+
<!-- END_TF_DOCS -->

modules/mpc-backup-vault/main.tf

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# ***************************************
2+
# Local variables
3+
# ***************************************
4+
resource "random_id" "mpc_party_suffix" {
5+
byte_length = 4
6+
}
7+
locals {
8+
backup_bucket_name = "${var.bucket_prefix}-${var.party_name}-${random_id.mpc_party_suffix.hex}"
9+
}
10+
11+
# ***************************************
12+
# S3 Buckets for Vault Private Storage
13+
# ***************************************
14+
resource "aws_s3_bucket" "backup_bucket" {
15+
force_destroy = true
16+
bucket = local.backup_bucket_name
17+
tags = merge(var.tags, {
18+
"Name" = local.backup_bucket_name
19+
"Type" = "backup-vault"
20+
"Party" = var.party_name
21+
"Purpose" = "mpc-backup-storage"
22+
})
23+
}
24+
25+
resource "aws_s3_bucket_ownership_controls" "backup_bucket" {
26+
bucket = aws_s3_bucket.backup_bucket.id
27+
rule {
28+
object_ownership = "BucketOwnerEnforced"
29+
}
30+
}
31+
32+
resource "aws_s3_bucket_versioning" "backup_bucket" {
33+
bucket = aws_s3_bucket.backup_bucket.id
34+
versioning_configuration {
35+
status = "Enabled"
36+
}
37+
}
38+
39+
resource "aws_s3_bucket_public_access_block" "backup_bucket" {
40+
bucket = aws_s3_bucket.backup_bucket.id
41+
block_public_acls = true
42+
block_public_policy = true
43+
ignore_public_acls = true
44+
restrict_public_buckets = true
45+
}
46+
47+
resource "aws_s3_bucket_policy" "backup_bucket" {
48+
bucket = aws_s3_bucket.backup_bucket.id
49+
policy = jsonencode({
50+
Version = "2012-10-17"
51+
Statement = [
52+
{
53+
Sid = "AllowCrossAccountBackup"
54+
Effect = "Allow"
55+
Principal = {
56+
AWS = "arn:aws:iam::${var.bucket_cross_account_id}:root"
57+
}
58+
Action = "s3:*"
59+
Resource = [
60+
"arn:aws:s3:::${aws_s3_bucket.backup_bucket.id}",
61+
"arn:aws:s3:::${aws_s3_bucket.backup_bucket.id}/*"
62+
]
63+
}
64+
]
65+
})
66+
}
67+
68+
# ***************************************
69+
# IAM Role & Policy for MPC Backup Vault
70+
# ***************************************
71+
72+
# Trust policy: Allow trusted principals to assume this role
73+
data "aws_iam_policy_document" "assume_role" {
74+
statement {
75+
actions = ["sts:AssumeRole"]
76+
effect = "Allow"
77+
principals {
78+
type = "AWS"
79+
identifiers = var.trusted_principal_arns
80+
}
81+
}
82+
}
83+
84+
resource "aws_iam_role" "mpc_backup_role" {
85+
name = "mpc-backup-${var.party_name}"
86+
assume_role_policy = data.aws_iam_policy_document.assume_role.json
87+
tags = var.tags
88+
}
89+
90+
# Policy allowing access to the bucket
91+
resource "aws_iam_policy" "mpc_aws" {
92+
name = "mpc-backup-${var.party_name}"
93+
policy = jsonencode({
94+
Version = "2012-10-17"
95+
Statement = [
96+
{
97+
Sid = "AllowObjectActions"
98+
Effect = "Allow"
99+
Action = "s3:*Object"
100+
Resource = [
101+
"arn:aws:s3:::${aws_s3_bucket.backup_bucket.id}/*"
102+
]
103+
},
104+
{
105+
Sid = "AllowListBucket"
106+
Effect = "Allow"
107+
Action = "s3:ListBucket"
108+
Resource = [
109+
"arn:aws:s3:::${aws_s3_bucket.backup_bucket.id}"
110+
]
111+
}
112+
]
113+
})
114+
}
115+
116+
# Attach policy to the role
117+
resource "aws_iam_role_policy_attachment" "mpc_backup_attach" {
118+
role = aws_iam_role.mpc_backup_role.name
119+
policy_arn = aws_iam_policy.mpc_aws.arn
120+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
output "bucket_name" {
2+
description = "The name of the created S3 bucket"
3+
value = aws_s3_bucket.backup_bucket.id
4+
}
5+
6+
output "bucket_arn" {
7+
description = "The ARN of the created S3 bucket"
8+
value = aws_s3_bucket.backup_bucket.arn
9+
}
10+
11+
output "role_name" {
12+
description = "The name of the IAM role created for accessing the bucket"
13+
value = aws_iam_role.mpc_backup_role.name
14+
}
15+
16+
output "role_arn" {
17+
description = "The ARN of the IAM role created for accessing the bucket"
18+
value = aws_iam_role.mpc_backup_role.arn
19+
}

0 commit comments

Comments
 (0)