diff --git a/RUNBOOK.md b/RUNBOOK.md index acb235f..b057c5f 100644 --- a/RUNBOOK.md +++ b/RUNBOOK.md @@ -204,6 +204,34 @@ Both API Keys and Secrets keys are generated by you. `api_key` must be a UUID, ` See [Peer information and credential exchange](#8-peer-information-and-credential-exchange) below for a recommendation on how to exchange credentials between peers. +#### Keystore backend + +`verifier.secrets.bootstrap` also selects where the verifier's **signing key** lives: +`keystoreBackend: postgres` (default) or `keystoreBackend: kms`. + +**On `externalSecret`, the chart writes the keystore block for you** from `keystoreBackend` and +`verifier.secrets.bootstrap.kms.*`. + +**On `gcpSecretStore`, `awsSecretStore` and `existingSecret` you write `secrets.toml` yourself** and the +chart only mounts it. `keystoreBackend` and `kms.*` are ignored on those paths. For production, where a +managed KMS is recommended over a Postgres-held key, the block you need is: + +```toml +[keystore] +backend = "kms" + +[keystore.kms] +# "aws" or "gcp". Required; there is no default. +provider = "gcp" +# AWS: a Key ID or ARN. GCP: a CryptoKeyVersion resource name. +ecdsa_key_id = "projects/

/locations//keyRings//cryptoKeys//cryptoKeyVersions/1" +``` + +Credentials to use KMS come from the cloud's authentication mechanism, see [Service Accounts](#service-accounts) below. + +The full reference, including per-cloud IAM guidance, is +[`secrets.documented.toml`](https://github.com/smartcontractkit/chainlink-ccv/blob/main/docs/config/bootstrap/secrets.documented.toml). + ### Ingress You can configure an ingress to the aggregator, which must be exposed to the internet, using one of these three values: diff --git a/charts/ccv-cell/README.md b/charts/ccv-cell/README.md index c9e6711..1566b87 100644 --- a/charts/ccv-cell/README.md +++ b/charts/ccv-cell/README.md @@ -63,6 +63,9 @@ A CCV Cell also has a few external pre-requisites for a production grade deploym - A Key Management Service (KMS) solution: - While the application supports holding the signing key in PostgreSQL, this is not recommended for production. - Instead, use a managed service for signing. + - Configure it with `verifier.secrets.bootstrap.keystoreBackend: kms`, or by writing the `[keystore.kms]` + block in `secrets.toml` yourself. See the [runbook](../../RUNBOOK.md#keystore-backend) and + [`secrets.documented.toml`](https://github.com/smartcontractkit/chainlink-ccv/blob/main/docs/config/bootstrap/secrets.documented.toml). - **We strongly recommend that, for production, you configure alerts for unexpected use of this key. Only the ccv-cell should be accessing this service.** - A Cloud IAM Service Account: @@ -355,8 +358,9 @@ A CCV Cell also has a few external pre-requisites for a production grade deploym | verifier.secrets.bootstrap.gcpSecretStore.secretProviderClass.name | string | `""` | Name of the SecretProviderClass resource to create. | | verifier.secrets.bootstrap.gcpSecretStore.secretVersionResourceName | string | `""` | Fully-qualified GCP Secret Manager secret version resource name, e.g. `projects//secrets//versions/latest`. | | verifier.secrets.bootstrap.keystoreBackend | string | `"postgres"` | Keystore backend: `postgres` or `kms`. | -| verifier.secrets.bootstrap.kms.ecdsaKeyId | string | `""` | AWS KMS key ID for the ECDSA key (only when `keystoreBackend` is `kms`). | -| verifier.secrets.bootstrap.kms.ed25519KeyId | string | `""` | AWS KMS key ID for the Ed25519 key (only when `keystoreBackend` is `kms`). | +| verifier.secrets.bootstrap.kms.ecdsaKeyId | string | `""` | KMS key for the ECDSA (secp256k1) signing key. Required when `keystoreBackend` is `kms`. AWS: a Key ID or ARN. GCP: a CryptoKeyVersion resource name (`projects/

/locations//keyRings//cryptoKeys//cryptoKeyVersions/`). Scope the workload's credentials to exactly this key. See [KeystoreConfig](https://github.com/smartcontractkit/chainlink-ccv/blob/main/bootstrap/config.go) for the per-cloud IAM guidance. | +| verifier.secrets.bootstrap.kms.ed25519KeyId | string | `""` | KMS key for the Ed25519 (CSA) key, same format as `ecdsaKeyId`. Only needed when running against a Job Distributor. Leave empty for this chart, which runs `local_app_config`. | +| verifier.secrets.bootstrap.kms.provider | string | `""` | Cloud KMS provider: `aws` or `gcp`. Required when `keystoreBackend` is `kms`. | | verifier.secrets.bootstrap.labels | object | `{}` | Labels to add to the verifier bootstrap Secret. | | verifier.secrets.bootstrap.type | string | `"externalSecret"` | Secret provisioning strategy: `externalSecret`, `existingSecret`, `gcpSecretStore`, `awsSecretStore`, or `azureKeyVault`. Configure the values below for the chosen type. | | verifier.secrets.bootstrapConfig.annotations | object | `{}` | Annotations to add to the verifier bootstrap-config Secret (non-values types only). | diff --git a/charts/ccv-cell/README.md.gotmpl b/charts/ccv-cell/README.md.gotmpl index 99c16e5..7ad7396 100644 --- a/charts/ccv-cell/README.md.gotmpl +++ b/charts/ccv-cell/README.md.gotmpl @@ -62,6 +62,9 @@ A CCV Cell also has a few external pre-requisites for a production grade deploym - A Key Management Service (KMS) solution: - While the application supports holding the signing key in PostgreSQL, this is not recommended for production. - Instead, use a managed service for signing. + - Configure it with `verifier.secrets.bootstrap.keystoreBackend: kms`, or by writing the `[keystore.kms]` + block in `secrets.toml` yourself. See the [runbook](../../RUNBOOK.md#keystore-backend) and + [`secrets.documented.toml`](https://github.com/smartcontractkit/chainlink-ccv/blob/main/docs/config/bootstrap/secrets.documented.toml). - **We strongly recommend that, for production, you configure alerts for unexpected use of this key. Only the ccv-cell should be accessing this service.** - A Cloud IAM Service Account: diff --git a/charts/ccv-cell/templates/verifier/externalsecret.yaml b/charts/ccv-cell/templates/verifier/externalsecret.yaml index 58794f4..4245679 100644 --- a/charts/ccv-cell/templates/verifier/externalsecret.yaml +++ b/charts/ccv-cell/templates/verifier/externalsecret.yaml @@ -86,8 +86,11 @@ spec: password = "{{ `{{ .keystore_password }}` }}" {{- else if eq .Values.verifier.secrets.bootstrap.keystoreBackend "kms" }} [keystore.kms] + provider = {{ required "verifier.secrets.bootstrap.kms.provider is required when keystoreBackend is kms (aws or gcp)" .Values.verifier.secrets.bootstrap.kms.provider | quote }} ecdsa_key_id = {{ .Values.verifier.secrets.bootstrap.kms.ecdsaKeyId | quote }} - ed25519_key_id = {{ .Values.verifier.secrets.bootstrap.kms.ed25519KeyId | quote }} + {{- with .Values.verifier.secrets.bootstrap.kms.ed25519KeyId }} + ed25519_key_id = {{ . | quote }} + {{- end }} {{- else }} {{- fail (print "Storage backend '" .Values.verifier.secrets.bootstrap.keystoreBackend "' is invalid") }} {{- end }} diff --git a/charts/ccv-cell/values.schema.json b/charts/ccv-cell/values.schema.json index a89e23a..30c0de8 100644 --- a/charts/ccv-cell/values.schema.json +++ b/charts/ccv-cell/values.schema.json @@ -279,6 +279,7 @@ "kms": { "type": "object", "properties": { + "provider": { "type": "string", "enum": ["", "aws", "gcp"] }, "ecdsaKeyId": { "type": "string" }, "ed25519KeyId": { "type": "string" } } diff --git a/charts/ccv-cell/values.yaml b/charts/ccv-cell/values.yaml index cc2ed6f..a0013a1 100644 --- a/charts/ccv-cell/values.yaml +++ b/charts/ccv-cell/values.yaml @@ -980,10 +980,18 @@ verifier: keystoreBackend: postgres kms: - # -- AWS KMS key ID for the ECDSA key (only when `keystoreBackend` is `kms`). - ecdsaKeyId: "" # "arn:aws:kms:us-east-1:...:key/abc123-..." - # -- AWS KMS key ID for the Ed25519 key (only when `keystoreBackend` is `kms`). - ed25519KeyId: "" # "arn:aws:kms:us-east-1:...:key/def456-..." + # -- Cloud KMS provider: `aws` or `gcp`. Required when `keystoreBackend` is `kms`. + provider: "" + # -- KMS key for the ECDSA (secp256k1) signing key. Required when `keystoreBackend` is `kms`. + # AWS: a Key ID or ARN. GCP: a CryptoKeyVersion resource name + # (`projects/

/locations//keyRings//cryptoKeys//cryptoKeyVersions/`). + # Scope the workload's credentials to exactly this key. See + # [KeystoreConfig](https://github.com/smartcontractkit/chainlink-ccv/blob/main/bootstrap/config.go) + # for the per-cloud IAM guidance. + ecdsaKeyId: "" + # -- KMS key for the Ed25519 (CSA) key, same format as `ecdsaKeyId`. Only needed when running + # against a Job Distributor. Leave empty for this chart, which runs `local_app_config`. + ed25519KeyId: "" # -- Secret provisioning strategy: `externalSecret`, `existingSecret`, `gcpSecretStore`, `awsSecretStore`, or `azureKeyVault`. # Configure the values below for the chosen type.