Skip to content

Key Management Service

Refer to the KMS blog post for more details on creating an AWS user with access to a master encryption key.

Nodes are the network resources responsible for transaction execution, block signing/consensus and maintaining the ledger. They are the critical piece to the entire blockchain apparatus, and as such, their key materials are of paramount importance to the security and integrity of the network. Kaleido employs multiple measures to protect these keys.

Firstly, key materials are always generated and destroyed along with the node and never leave the node’s file system. No copies are ever saved in the backend configuration databases, ensuring isolation from the various microservices and platform layers. When a new node gets added to an environment, Kaleido generates the keys and saves them to the node’s configuration files that are only accessible by the containers inside the Kubernetes pod for the node. The keys stay there until the node gets deleted, at which point the mounted directories containing the configurations files get cleaned up. As a result, private keys are always “at rest” and never “in-transit”. This eliminates a significant attack surface and keeps the keys safe from malicious hackers that attack by sniffing the network packages.

As an additional security measure, Kaleido offers the option to encrypt the mounted key materials with a master encryption key managed by a key vault service. On a per node basis, users can elect for further protection by implementing Amazon’s Key Management Service (KMS). With KMS enabled, the key materials on the node’s file system will be encrypted by the master key in the user’s KMS, and only ever decrypted with that same master key when the node starts up. This further secures the attack surface involving the mounted file system and allows the user to revoke access to the master key if there is reason to believe the node is under attack. KMS also provides a transparent audit trail for all decryption requests, allowing any illegitimate or abnormal requests to be quickly identified.

Key Management Service integration for Kaledio

Available with both AWS Key Management Service and Azure Key Vault

Configuring an IAM Role

NOTE: Support for IAM user-based longterm credentials (the AWS cloud configuration structure offered on previous Kaleido releases) is being deprecated. For newly created AWS configurations, you must use the IAM role approach outlined below.

  • Log into the AWS console and navigate to the IAM Service.
  • IAM roles will be used to grant Kaleido access to your KMS instance storing the master encryption key. Refer to the AWS guide for more information on IAM roles.
  • Click the Roles tab in the IAM navigation panel and proceed to Create a New Role.
  • Select Another AWS Account as trusted entity and use Kaleido's account ID 271815176711 in the Account ID field.
  • Skip Permissions, Tags, and finish creating role by specifying a Role Name.

Creating an Encryption Key

  • Navigate to the Key Management Service and click on the Customer Managed Keys tab in the navigation panel.
  • Click on Create key.
  • Select Symmetric as the key type and click Next.
  • Add an alias for your key, for example kms-key-for-kaleido and and click Next.
  • Select the key administrator and click Next.
  • Select the role created with Kaleido's account as a trusted entity. This will allow the role to leverage the key. Click Next.
  • Click Next to review your settings and finish creating the key by clicking on Finish.

Generating Kaleido IDs

You will need to use the administrative API to generate your KMS configuration on Kaleido. The API response will return two unique strings - configuration_id & external_id_seed - that will be used to edit your IAM role's trust policy. You will need to assemble an external_id string with a syntax of ${configuration_id}-${external_id_seed}-external-id, where configuration_id is ID of the KMS configuration object and external_id_seed is a unique value generated by Kaleido. Both are returned in the API call to generate the KMS configuration object.

An example request to create an IAM role based KMS configuration in your Kaleido environment:

https://console.kaleido.io/api/v1/consortia/:consortium_id/environments/:environment_id/configurations
{
    "membership_id": "<membership id belonging to your organization>",
    "name": "role-based-kms-config",
    "type": "kms",
    "details": {
        "provider": "aws",
        "region": "us-east-2",
        "role_arn": "<arn for the role you created to give kaleido access>",
        "master_key": "<AWS master key ARN or Alias or Key ID>"
    }   
}

Sample response

{
    "membership_id": "<membership id belonging to your organization>",
    "name": "role-based-kms-config",
    "type": "kms",
    "details": {
        "provider": "aws",
        "region": "us-east-2",
        "role_arn": "<arn for the role you created to give kaleido access>",
        "master_key": "<AWS master key ARN or Alias or Key ID>"
        "external_id_seed": "<unique id generated by kaleido>"
    },
    "_id": "<configuration id>",
    "_revision": "0",
    "created_at": "2021-06-08T02:32:46.152Z",
    "environment_id": "<environment id>"
}

If "_id" in the above JSON response is u0jj4apxhw and "external_id_seed" is u0f5drkxrb, then the fully assembled external_id string would be u0jj4apxhw-u0f5drkxrb-external-id.

Editing your IAM Role's Trust Policy

You now need to edit the trust policy of the IAM role used in your KMS configuration to include the external_id string. You can do this using following steps

  • Log into the AWS console and navigate to your IAM service.
  • Next, click the Roles tab in the navigation panel.
  • Click the Trust Relationships button and then Edit trust relationship button.
  • Update the policy document to use the external_id string as the Condition value. The updated policy document resembles the following:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::271815176711:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "<external id string here>"
        }
      }
    }
  ]
}

Again, please refer to the following AWS guide to understand in detail how to use IAM roles and why they are required.