

# Create an active branch key
<a name="create-branch-keys"></a>

A *branch key* is a data key derived from an AWS KMS key that the AWS KMS Hierarchical keyring uses to reduce the number of calls made to AWS KMS. The *active* branch key is the most recent branch key version. The Hierarchical keyring generates a unique data key for every encrypt request and encrypts each data key with a unique wrapping key derived from the active branch key.

To create a new active branch key, you must [statically configure](keystore-actions.md#static-keystore) your key store actions. `CreateKey` is a privileged operation that adds the KMS key ARN specified in your key store actions configuration to your key store allowlist. Then, the KMS key is used to generate the new active branch key. We recommend limiting access to this operation because once a KMS key is added to the key store, it cannot be deleted.

You can allowlist one KMS key in your key store, or you can allowlist multiple KMS keys by updating the KMS key ARN that you specify in your key store actions configuration and calling `CreateKey` again. If you allowlist multiple KMS keys, your key store users should configure their key store actions for discovery so that they can use any of the allowlisted keys in the key store that they have access to. For more information, see [Configure key store actions](keystore-actions.md).

**Required permissions**  
To create branch keys, you need [kms:GenerateDataKeyWithoutPlaintext](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKeyWithoutPlaintext.html) and [kms:ReEncrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_ReEncrypt.html) permissions on the KMS key specified in your key store actions.

**Create a branch key**  
The following operation creates a new active branch key using the KMS key that you[specified in your key store actions configuration](keystore-actions.md#static-keystore), and adds the active branch key to the DynamoDB table that serves as your key store.

When you call `CreateKey`, you can choose to specify the following optional values.
+ `branchKeyIdentifier`: defines a custom `branch-key-id`.

  To create a custom `branch-key-id`, you must also include an additional encryption context with the `encryptionContext` parameter.
+ `encryptionContext`: defines an optional set of non-secret key–value pairs that provides additional authenticated data (AAD) in the encryption context included in the [kms:GenerateDataKeyWithoutPlaintext](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKeyWithoutPlaintext.html) call.

  This additional encryption context is displayed with the `aws-crypto-ec:` prefix.

------
#### [ Java ]

```
final Map<String, String> additionalEncryptionContext = Collections.singletonMap("Additional Encryption Context for",
	         "custom branch key id");
	             
	 final String BranchKey = keystore.CreateKey(
	         CreateKeyInput.builder()
	                 .branchKeyIdentifier(custom-branch-key-id) //OPTIONAL
	                 .encryptionContext(additionalEncryptionContext) //OPTIONAL              
	                 .build()).branchKeyIdentifier();
```

------
#### [ C\$1 / .NET ]

```
var additionalEncryptionContext = new Dictionary<string, string>();
	 additionalEncryptionContext.Add("Additional Encryption Context for", "custom branch key id");
	         
	 var branchKeyId = keystore.CreateKey(new CreateKeyInput
	 {
	     BranchKeyIdentifier = "custom-branch-key-id", // OPTIONAL
	     EncryptionContext = additionalEncryptionContext // OPTIONAL
	 });
```

------
#### [ Python ]

```
additional_encryption_context = {"Additional Encryption Context for": "custom branch key id"}

branch_key_id: str = keystore.create_key(
    CreateKeyInput(
        branch_key_identifier = "custom-branch-key-id", # OPTIONAL
        encryption_context = additional_encryption_context, # OPTIONAL
    )
)
```

------
#### [ Rust ]

```
let additional_encryption_context = HashMap::from([
    ("Additional Encryption Context for".to_string(), "custom branch key id".to_string())
]);

let branch_key_id = keystore.create_key()
    .branch_key_identifier("custom-branch-key-id") // OPTIONAL
    .encryption_context(additional_encryption_context) // OPTIONAL
    .send()
    .await?
    .branch_key_identifier
    .unwrap();
```

------
#### [ Go ]

```
encryptionContext := map[string]string{
    "Additional Encryption Context for": "custom branch key id",
}

branchKey, err := keyStore.CreateKey(context.Background(), keystoretypes.CreateKeyInput{
    BranchKeyIdentifier: &customBranchKeyId,
    EncryptionContext:   additional_encryption_context,
})
if err != nil {
    return "", err
}
```

------

First, the `CreateKey` operation generates the following values.
+ A version 4 [Universally Unique Identifier](https://www.ietf.org/rfc/rfc4122.txt) (UUID) for the `branch-key-id` (unless you specified a custom `branch-key-id`).
+ A version 4 UUID for the branch key version
+ A `timestamp` in the [ISO 8601 date and time format](https://www.iso.org/iso-8601-date-and-time-format.html) in Coordinated Universal Time (UTC).

Then, the `CreateKey` operation calls [kms:GenerateDataKeyWithoutPlaintext](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKeyWithoutPlaintext.html) using the following request.

```
{
	    "EncryptionContext": { 
	       "branch-key-id" : "branch-key-id",
	       "type" : "type",
	       "create-time" : "timestamp",
	       "logical-key-store-name" : "the logical table name for your key store",
	       "kms-arn" : the KMS key ARN,
	       "hierarchy-version" : "1",
	       "aws-crypto-ec:contextKey": "contextValue"
	    },
	    "KeyId": "the KMS key ARN you specified in your key store actions",
	    "NumberOfBytes": "32"
	 }
```

Next, the `CreateKey` operation calls [kms:ReEncrypt](https://docs.aws.amazon.com/kms/latest/APIReference/AAPI_ReEncrypt.html) to create an active record for the branch key by updating the encryption context.

Last, the `CreateKey` operation calls [ddb:TransactWriteItems](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html) to write a new item that will persist the branch key in the table you created in **Step 2**. The item has the following attributes.

```
{
	     "branch-key-id" : branch-key-id,
	     "type" : "branch:ACTIVE",
	     "enc" : the branch key returned by the GenerateDataKeyWithoutPlaintext call,
	     "version": "branch:version:the branch key version UUID",
	     "create-time" : "timestamp",
	     "kms-arn" : "the KMS key ARN you specified in Step 1",
	     "hierarchy-version" : "1",
	     "aws-crypto-ec:contextKey": "contextValue"
 }
```