diff --git a/modules/mpc-party/variables.tf b/modules/mpc-party/variables.tf
index 89cb3fa..339cd1f 100644
--- a/modules/mpc-party/variables.tf
+++ b/modules/mpc-party/variables.tf
@@ -353,22 +353,12 @@ variable "kms_cross_account_kms_key_id" {
type = string
description = "KMS key ID of KMS key created in a different AWS account"
default = ""
-
- validation {
- condition = !var.kms_use_cross_account_kms_key || (var.kms_use_cross_account_kms_key && var.kms_cross_account_kms_key_id != "")
- error_message = "kms_cross_account_kms_key_id must be provided when kms_use_cross_account_kms_key is true."
- }
}
variable "kms_cross_account_connector_txsender_key_id" {
type = string
description = "KMS key ID of Connector TxSender KMS key created in a different AWS account"
default = ""
-
- validation {
- condition = !var.kms_use_cross_account_kms_key || (var.kms_use_cross_account_kms_key && var.kms_cross_account_connector_txsender_key_id != "")
- error_message = "kms_cross_account_connector_txsender_key_id must be provided when kms_use_cross_account_kms_key is true."
- }
}
variable "kms_key_usage" {
diff --git a/modules/zama-protocol-pauser-wallet/README.md b/modules/zama-protocol-pauser-wallet/README.md
new file mode 100644
index 0000000..1112b71
--- /dev/null
+++ b/modules/zama-protocol-pauser-wallet/README.md
@@ -0,0 +1,63 @@
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.0 |
+| [aws](#requirement\_aws) | >= 6.0 |
+| [kubernetes](#requirement\_kubernetes) | >= 2.23 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [aws](#provider\_aws) | >= 6.0 |
+| [kubernetes](#provider\_kubernetes) | >= 2.23 |
+
+## Modules
+
+| Name | Source | Version |
+|------|--------|---------|
+| [iam\_assumable\_role\_tx\_sender](#module\_iam\_assumable\_role\_tx\_sender) | terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc | 5.48.0 |
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [aws_iam_policy.app_kms_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
+| [aws_kms_alias.tx_sender](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource |
+| [aws_kms_external_key.tx_sender](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_external_key) | resource |
+| [kubernetes_config_map.mpc_party_config](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/config_map) | resource |
+| [kubernetes_namespace.zama_protocol_namespace](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/namespace) | resource |
+| [kubernetes_service_account.tx_sender_irsa](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/service_account) | resource |
+| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
+| [aws_eks_cluster.cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/eks_cluster) | data source |
+| [aws_iam_policy_document.tx_sender_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [app\_name](#input\_app\_name) | Name of the role | `string` | `"zama-protocol-pause"` | no |
+| [cluster\_name](#input\_cluster\_name) | Name of the cluster | `string` | `null` | no |
+| [k8s\_config\_map\_create](#input\_k8s\_config\_map\_create) | Whether to create the configmap for that holds AWS\_KMS\_KEY\_ID | `bool` | `true` | no |
+| [k8s\_config\_map\_name](#input\_k8s\_config\_map\_name) | Name of the configmap | `string` | `"zama-protocol-pause"` | no |
+| [k8s\_create\_namespace](#input\_k8s\_create\_namespace) | Whether to create the namespace if it doesn't exist | `bool` | `false` | no |
+| [k8s\_namespace](#input\_k8s\_namespace) | Namespace of the application | `string` | `"zama-protocol"` | no |
+| [k8s\_service\_account\_create](#input\_k8s\_service\_account\_create) | Whether to create the service account for the KMS key | `bool` | `true` | no |
+| [k8s\_service\_account\_name](#input\_k8s\_service\_account\_name) | Name of the service account | `string` | `"zama-protocol-pause"` | no |
+| [kms\_cross\_account\_iam\_role\_arn](#input\_kms\_cross\_account\_iam\_role\_arn) | ARN of cross-account IAM role allowed for usage of KMS key | `string` | `null` | no |
+| [kms\_cross\_account\_kms\_key\_id](#input\_kms\_cross\_account\_kms\_key\_id) | KMS key ID of KMS key created in a different AWS account | `string` | `""` | no |
+| [kms\_deletion\_window\_in\_days](#input\_kms\_deletion\_window\_in\_days) | Deletion window in days for KMS key | `number` | `30` | no |
+| [kms\_key\_spec](#input\_kms\_key\_spec) | Specification for the txsender (e.g., ECC\_SECG\_P256K1 for Ethereum key signing) | `string` | `"ECC_SECG_P256K1"` | no |
+| [kms\_key\_usage](#input\_kms\_key\_usage) | Key usage for txsender | `string` | `"SIGN_VERIFY"` | no |
+| [kms\_use\_cross\_account\_kms\_key](#input\_kms\_use\_cross\_account\_kms\_key) | Whether a KMS key has been created in a different AWS account | `bool` | `false` | no |
+| [tags](#input\_tags) | The tags for the KMS keys | `map(string)` | n/a | yes |
+| [zama\_protocol\_pauser\_iam\_assumable\_role\_enabled](#input\_zama\_protocol\_pauser\_iam\_assumable\_role\_enabled) | Whether to enable the IAM assumable role for the application | `bool` | `false` | no |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [aws\_kms\_key\_id](#output\_aws\_kms\_key\_id) | Summary of the KMS Key for the application |
+
diff --git a/modules/zama-protocol-pauser-wallet/main.tf b/modules/zama-protocol-pauser-wallet/main.tf
new file mode 100644
index 0000000..7558ec0
--- /dev/null
+++ b/modules/zama-protocol-pauser-wallet/main.tf
@@ -0,0 +1,155 @@
+# ************
+# Data Sources
+# ************
+data "aws_caller_identity" "current" {}
+
+data "aws_eks_cluster" "cluster" {
+ name = var.cluster_name
+}
+
+# Create Kubernetes namespace (optional)
+resource "kubernetes_namespace" "zama_protocol_namespace" {
+ count = var.k8s_create_namespace ? 1 : 0
+
+ metadata {
+ name = var.k8s_namespace
+ }
+}
+
+# ************
+# Application Ethereum Key
+# ************
+data "aws_iam_policy_document" "tx_sender_policy" {
+ statement {
+ effect = "Allow"
+ principals {
+ type = "AWS"
+ identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"]
+ }
+ actions = [
+ "kms:Create*",
+ "kms:Describe*",
+ "kms:Enable*",
+ "kms:List*",
+ "kms:Put*",
+ "kms:Update*",
+ "kms:Revoke*",
+ "kms:Disable*",
+ "kms:Get*",
+ "kms:Delete*",
+ "kms:TagResource",
+ "kms:UntagResource",
+ "kms:ScheduleKeyDeletion",
+ "kms:CancelKeyDeletion",
+ "kms:ImportKeyMaterial",
+ "kms:DeleteImportedKeyMaterial"
+ ]
+ resources = ["*"]
+ }
+ statement {
+ effect = "Allow"
+ principals {
+ type = "AWS"
+ identifiers = [var.kms_cross_account_iam_role_arn != null ? var.kms_cross_account_iam_role_arn : "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"]
+ }
+ actions = ["kms:DescribeKey", "kms:GetPublicKey", "kms:Sign", "kms:Verify"]
+ resources = ["*"]
+ }
+}
+
+# ************
+# AWS External KMS Key for Ethereum TxSender
+# ************
+
+resource "aws_kms_external_key" "tx_sender" {
+ count = var.kms_use_cross_account_kms_key ? 0 : 1
+ description = "Application ${var.app_name} tx sender key for ${var.cluster_name}"
+ key_usage = var.kms_key_usage
+ key_spec = var.kms_key_spec
+ deletion_window_in_days = var.kms_deletion_window_in_days
+ tags = var.tags
+ policy = data.aws_iam_policy_document.tx_sender_policy.json
+}
+
+# ************
+# KMS Key Alias for Application Ethereum TxSender Key
+# ************
+resource "aws_kms_alias" "tx_sender" {
+ count = var.kms_use_cross_account_kms_key ? 0 : 1
+
+ name = "alias/${var.app_name}-${var.cluster_name}"
+ target_key_id = aws_kms_external_key.tx_sender[0].id
+}
+
+resource "aws_iam_policy" "app_kms_policy" {
+ count = var.kms_use_cross_account_kms_key ? 0 : 1
+
+ name = "${var.app_name}-${var.cluster_name}"
+ policy = jsonencode({
+ Version = "2012-10-17"
+ Statement = [
+ {
+ Sid = "AllowPauserJobToUseKeyForEthereumTxSender"
+ Effect = "Allow",
+ Action = [
+ "kms:DescribeKey",
+ "kms:GetPublicKey",
+ "kms:Sign",
+ "kms:Verify"
+ ],
+ Resource = aws_kms_external_key.tx_sender[0].arn
+ },
+ ]
+ })
+}
+
+module "iam_assumable_role_tx_sender" {
+ count = var.zama_protocol_pauser_iam_assumable_role_enabled ? 1 : 0
+ source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
+ version = "5.48.0"
+ provider_url = data.aws_eks_cluster.cluster.identity[0].oidc[0].issuer
+ create_role = true
+ role_name = "${var.app_name}-${var.cluster_name}"
+ oidc_fully_qualified_subjects = ["system:serviceaccount:${var.k8s_namespace}:${var.k8s_service_account_name}"]
+ role_policy_arns = [aws_iam_policy.app_kms_policy[0].arn]
+}
+
+resource "kubernetes_service_account" "tx_sender_irsa" {
+ count = var.zama_protocol_pauser_iam_assumable_role_enabled && var.k8s_service_account_create ? 1 : 0
+ metadata {
+ name = var.k8s_service_account_name
+ namespace = var.k8s_namespace
+ annotations = {
+ "eks.amazonaws.com/role-arn" = module.iam_assumable_role_tx_sender[0].iam_role_arn
+ }
+ }
+}
+
+locals {
+ kms_key_id = var.kms_use_cross_account_kms_key ? var.kms_cross_account_kms_key_id : aws_kms_external_key.tx_sender[0].id
+}
+
+resource "kubernetes_config_map" "mpc_party_config" {
+ count = var.k8s_config_map_create ? 1 : 0
+
+ metadata {
+ name = var.k8s_config_map_name
+ namespace = var.k8s_namespace
+
+ labels = {
+ "app.kubernetes.io/name" = var.app_name
+ "app.kubernetes.io/component" = "config"
+ "app.kubernetes.io/managed-by" = "terraform"
+ }
+
+ annotations = {
+ "terraform.io/module" = "zama-protocol-pauser-wallet"
+ }
+ }
+
+ data = {
+ "AWS_KMS_KEY_ID" = local.kms_key_id
+ }
+
+ depends_on = [kubernetes_namespace.zama_protocol_namespace]
+}
diff --git a/modules/zama-protocol-pauser-wallet/outputs.tf b/modules/zama-protocol-pauser-wallet/outputs.tf
new file mode 100644
index 0000000..f9a6347
--- /dev/null
+++ b/modules/zama-protocol-pauser-wallet/outputs.tf
@@ -0,0 +1,4 @@
+output "aws_kms_key_id" {
+ description = "Summary of the KMS Key for the application"
+ value = local.kms_key_id
+}
diff --git a/modules/zama-protocol-pauser-wallet/variables.tf b/modules/zama-protocol-pauser-wallet/variables.tf
new file mode 100644
index 0000000..7a24207
--- /dev/null
+++ b/modules/zama-protocol-pauser-wallet/variables.tf
@@ -0,0 +1,101 @@
+# ************
+# General variables
+# ************
+variable "tags" {
+ type = map(string)
+ description = "The tags for the KMS keys"
+}
+
+# ************
+# Variables for usage in kms-for-mpc-party.tf
+# ************
+
+variable "cluster_name" {
+ type = string
+ description = "Name of the cluster"
+ default = null
+}
+
+variable "app_name" {
+ type = string
+ description = "Name of the role"
+ default = "zama-protocol-pause"
+}
+
+variable "k8s_config_map_name" {
+ type = string
+ description = "Name of the configmap"
+ default = "zama-protocol-pause"
+}
+
+variable "k8s_config_map_create" {
+ type = bool
+ description = "Whether to create the configmap for that holds AWS_KMS_KEY_ID"
+ default = true
+}
+
+variable "k8s_service_account_name" {
+ type = string
+ description = "Name of the service account"
+ default = "zama-protocol-pause"
+}
+
+variable "k8s_service_account_create" {
+ type = bool
+ description = "Whether to create the service account for the KMS key"
+ default = true
+}
+
+variable "k8s_namespace" {
+ type = string
+ description = "Namespace of the application"
+ default = "zama-protocol"
+}
+
+variable "k8s_create_namespace" {
+ description = "Whether to create the namespace if it doesn't exist"
+ type = bool
+ default = false
+}
+
+variable "zama_protocol_pauser_iam_assumable_role_enabled" {
+ type = bool
+ description = "Whether to enable the IAM assumable role for the application"
+ default = false
+}
+
+variable "kms_cross_account_iam_role_arn" {
+ type = string
+ description = "ARN of cross-account IAM role allowed for usage of KMS key"
+ default = null
+}
+
+variable "kms_key_usage" {
+ type = string
+ description = "Key usage for txsender"
+ default = "SIGN_VERIFY"
+}
+
+variable "kms_key_spec" {
+ description = "Specification for the txsender (e.g., ECC_SECG_P256K1 for Ethereum key signing)"
+ type = string
+ default = "ECC_SECG_P256K1"
+}
+
+variable "kms_deletion_window_in_days" {
+ type = number
+ description = "Deletion window in days for KMS key"
+ default = 30
+}
+
+variable "kms_use_cross_account_kms_key" {
+ type = bool
+ description = "Whether a KMS key has been created in a different AWS account"
+ default = false
+}
+
+variable "kms_cross_account_kms_key_id" {
+ type = string
+ description = "KMS key ID of KMS key created in a different AWS account"
+ default = ""
+}
diff --git a/modules/zama-protocol-pauser-wallet/versions.tf b/modules/zama-protocol-pauser-wallet/versions.tf
new file mode 100644
index 0000000..7639655
--- /dev/null
+++ b/modules/zama-protocol-pauser-wallet/versions.tf
@@ -0,0 +1,14 @@
+terraform {
+ required_version = ">= 1.0"
+
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 6.0"
+ }
+ kubernetes = {
+ source = "hashicorp/kubernetes"
+ version = ">= 2.23"
+ }
+ }
+}