15
15
CacheTypeDefault ,
16
16
CreateAwsKmsHierarchicalKeyringInput ,
17
17
DefaultCache ,
18
- GetBranchKeyIdInput ,
19
- GetBranchKeyIdOutput ,
20
18
)
21
19
from aws_cryptographic_materialproviders .mpl .references import IBranchKeyIdSupplier , IKeyring
22
20
from typing import Dict
25
23
from aws_encryption_sdk import CommitmentPolicy
26
24
from aws_encryption_sdk .exceptions import AWSEncryptionSDKClientError
27
25
26
+ from .example_branch_key_id_supplier import ExampleBranchKeyIdSupplier
27
+
28
28
module_root_dir = '/' .join (__file__ .split ("/" )[:- 1 ])
29
29
30
30
sys .path .append (module_root_dir )
@@ -73,39 +73,6 @@ def encrypt_and_decrypt_with_keyring(
73
73
branch_key_id_A : str = keystore .create_key (input = CreateKeyInput ()).branch_key_identifier
74
74
branch_key_id_B : str = keystore .create_key (input = CreateKeyInput ()).branch_key_identifier
75
75
76
- class ExampleBranchKeyIdSupplier (IBranchKeyIdSupplier ):
77
- """Example implementation of a branch key ID supplier."""
78
-
79
- branch_key_id_for_tenant_A : str
80
- branch_key_id_for_tenant_B : str
81
-
82
- def __init__ (self , tenant_1_id , tenant_2_id ):
83
- self .branch_key_id_for_tenant_A = tenant_1_id
84
- self .branch_key_id_for_tenant_B = tenant_2_id
85
-
86
- def get_branch_key_id (
87
- self ,
88
- # Change this to `native_input`
89
- input : GetBranchKeyIdInput # noqa pylint: disable=redefined-builtin
90
- ) -> GetBranchKeyIdOutput :
91
- """Returns branch key ID from the tenant ID in input's encryption context."""
92
- encryption_context : Dict [str , str ] = input .encryption_context
93
-
94
- if b"tenant" not in encryption_context :
95
- raise ValueError ("EncryptionContext invalid, does not contain expected tenant key value pair." )
96
-
97
- tenant_key_id : str = encryption_context .get (b"tenant" )
98
- branch_key_id : str
99
-
100
- if tenant_key_id == b"TenantA" :
101
- branch_key_id = self .branch_key_id_for_tenant_A
102
- elif tenant_key_id == b"TenantB" :
103
- branch_key_id = self .branch_key_id_for_tenant_B
104
- else :
105
- raise ValueError (f"Item does not contain valid tenant ID: { tenant_key_id = } " )
106
-
107
- return GetBranchKeyIdOutput (branch_key_id = branch_key_id )
108
-
109
76
# 5. Create a branch key supplier that maps the branch key id to a more readable format
110
77
branch_key_id_supplier : IBranchKeyIdSupplier = ExampleBranchKeyIdSupplier (
111
78
tenant_1_id = branch_key_id_A ,
@@ -132,8 +99,10 @@ def get_branch_key_id(
132
99
input = keyring_input
133
100
)
134
101
135
- # The Branch Key Id supplier uses the encryption context to determine which branch key id will
136
- # be used to encrypt data.
102
+ # 7. Create encryption context for both tenants.
103
+ # The Branch Key Id supplier uses the encryption context to determine which branch key id will
104
+ # be used to encrypt data.
105
+
137
106
# Create encryption context for TenantA
138
107
encryption_context_A : Dict [str , str ] = {
139
108
"tenant" : "TenantA" ,
@@ -154,7 +123,7 @@ def get_branch_key_id(
154
123
"the data you are handling" : "is what you think it is" ,
155
124
}
156
125
157
- # Encrypt the data for encryptionContextA & encryptionContextB
126
+ # 8. Encrypt the data for encryptionContextA & encryptionContextB
158
127
ciphertext_A , _ = client .encrypt (
159
128
source = EXAMPLE_DATA ,
160
129
keyring = hierarchical_keyring ,
@@ -166,8 +135,8 @@ def get_branch_key_id(
166
135
encryption_context = encryption_context_B
167
136
)
168
137
169
- # To attest that TenantKeyB cannot decrypt a message written by TenantKeyA
170
- # let's construct more restrictive hierarchical keyrings.
138
+ # 9. To attest that TenantKeyB cannot decrypt a message written by TenantKeyA,
139
+ # let's construct more restrictive hierarchical keyrings.
171
140
keyring_input_A : CreateAwsKmsHierarchicalKeyringInput = CreateAwsKmsHierarchicalKeyringInput (
172
141
key_store = keystore ,
173
142
branch_key_id = branch_key_id_A ,
@@ -198,6 +167,11 @@ def get_branch_key_id(
198
167
input = keyring_input_B
199
168
)
200
169
170
+ # 10. Demonstrate that data encrypted by one tenant's key
171
+ # cannot be decrypted with by a keyring specific to another tenant.
172
+
173
+ # Keyring with tenant B's branch key cannot decrypt data encrypted with tenant A's branch key
174
+ # This will fail and raise a AWSEncryptionSDKClientError, which we swallow ONLY for demonstration purposes.
201
175
try :
202
176
client .decrypt (
203
177
source = ciphertext_A ,
@@ -206,7 +180,8 @@ def get_branch_key_id(
206
180
except AWSEncryptionSDKClientError :
207
181
pass
208
182
209
- # This should fail
183
+ # Keyring with tenant A's branch key cannot decrypt data encrypted with tenant B's branch key.
184
+ # This will fail and raise a AWSEncryptionSDKClientError, which we swallow ONLY for demonstration purposes.
210
185
try :
211
186
client .decrypt (
212
187
source = ciphertext_B ,
@@ -215,7 +190,8 @@ def get_branch_key_id(
215
190
except AWSEncryptionSDKClientError :
216
191
pass
217
192
218
- # These should succeed
193
+ # 10. Demonstrate that data encrypted by one tenant's branch key can be decrypted by that tenant,
194
+ # and that the decrypted data matches the input data.
219
195
plaintext_bytes_A , _ = client .decrypt (
220
196
source = ciphertext_A ,
221
197
keyring = hierarchical_keyring_A
0 commit comments