Skip to content

Commit 276a31f

Browse files
authored
Try encrypting KMS key without encryption context first (#154)
1 parent 46a20d0 commit 276a31f

File tree

10 files changed

+63
-62
lines changed

10 files changed

+63
-62
lines changed

datadog_lambda/metric.py

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -231,29 +231,28 @@ def decrypt_kms_api_key(kms_client, ciphertext):
231231
decoded_bytes = base64.b64decode(ciphertext)
232232

233233
"""
234-
The Lambda console UI changed the way it encrypts environment variables. The current behavior
235-
as of May 2021 is to encrypt environment variables using the function name as an encryption
236-
context. Previously, the behavior was to encrypt environment variables without an encryption
237-
context. We need to try both, as supplying the incorrect encryption context will cause
238-
decryption to fail.
234+
When the API key is encrypted using the AWS console, the function name is added as an
235+
encryption context. When the API key is encrypted using the AWS CLI, no encryption context
236+
is added. We need to try decrypting the API key both with and without the encryption context.
239237
"""
240-
# Try with encryption context
238+
# Try without encryption context, in case API key was encrypted using the AWS CLI
241239
function_name = os.environ.get("AWS_LAMBDA_FUNCTION_NAME")
242240
try:
241+
plaintext = kms_client.decrypt(CiphertextBlob=decoded_bytes)[
242+
"Plaintext"
243+
].decode("utf-8")
244+
except ClientError:
245+
logger.debug(
246+
"Failed to decrypt ciphertext without encryption context, \
247+
retrying with encryption context"
248+
)
249+
# Try with encryption context, in case API key was encrypted using the AWS Console
243250
plaintext = kms_client.decrypt(
244251
CiphertextBlob=decoded_bytes,
245252
EncryptionContext={
246253
KMS_ENCRYPTION_CONTEXT_KEY: function_name,
247254
},
248255
)["Plaintext"].decode("utf-8")
249-
except ClientError:
250-
logger.debug(
251-
"Failed to decrypt ciphertext with encryption context, retrying without"
252-
)
253-
# Try without encryption context
254-
plaintext = kms_client.decrypt(CiphertextBlob=decoded_bytes)[
255-
"Plaintext"
256-
].decode("utf-8")
257256

258257
return plaintext
259258

scripts/run_integration_tests.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,8 @@ for handler_name in "${LAMBDA_HANDLERS[@]}"; do
200200
sed -E "s/(python )([0-9]\.[0-9]+\.[0-9]+)/\1XX/g" |
201201
# Strip out run ID (from function name, resource, etc.)
202202
sed -E "s/${!run_id}/XXXX/g" |
203+
# Normalize python-requests version
204+
sed -E "s/(User-Agent:python-requests\/)[0-9]+\.[0-9]+\.[0-9]+/\1X\.X\.X/g" |
203205
# Strip out trace/span/parent/timestamps
204206
sed -E "s/(\"trace_id\"\: \")[A-Z0-9\.\-]+/\1XXXX/g" |
205207
sed -E "s/(\"span_id\"\: \")[A-Z0-9\.\-]+/\1XXXX/g" |

tests/integration/snapshots/logs/async-metrics_python27.log

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,26 @@ START RequestId: XXXX Version: $LATEST
22
{"e": XXXX, "m": "aws.lambda.enhanced.invocations", "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python27", "resource:integration-tests-python-XXXX-async-metrics_python27", "cold_start:true", "memorysize:1024", "runtime:python2.7", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python27_X.X.X"], "v": 1}
33
{"e": XXXX, "m": "hello.dog", "t": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python27_X.X.X"], "v": 1}
44
{"e": XXXX, "m": "tests.integration.count", "t": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python27_X.X.X"], "v": 21}
5-
HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/2.25.1", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {}
6-
HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/2.25.1", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {}
5+
HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {}
6+
HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {}
77
{"traces": [[{"resource": "integration-tests-python-XXXX-async-metrics_python27", "name": "aws.lambda", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_sampling_priority_v1": 1, "system.pid": XXXX, "_dd.agent_psr": 1.0}, "parent_id": "XXXX", "meta": {"http.method": "GET", "runtime-id": "XXXX", "request_id": "XXXX", "function_trigger.event_source": "api-gateway", "cold_start": "true", "datadog_lambda": "X.X.X", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-async-metrics_python27", "dd_trace": "X.X.X", "_dd.origin": "lambda", "http.status_code": "200", "resource_names": "integration-tests-python-XXXX-async-metrics_python27", "function_trigger.event_source_arn": "arn:aws:apigateway:sa-east-1::/restapis/wt6mne2s9k/stages/test", "function_version": "$LATEST"}, "error": 0, "duration": XXXX, "type": "serverless", "span_id": "XXXX"}, {"resource": "requests.request", "name": "requests.request", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_dd.measured": 1}, "parent_id": "XXXX", "meta": {"http.status_code": "200", "http.url": "https://httpstat.us/200/", "_dd.origin": "lambda", "http.method": "GET"}, "error": 0, "duration": XXXX, "type": "http", "span_id": "XXXX"}, {"resource": "requests.request", "name": "requests.request", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_dd.measured": 1}, "parent_id": "XXXX", "meta": {"http.status_code": "400", "http.url": "https://httpstat.us/400/", "_dd.origin": "lambda", "http.method": "GET"}, "error": 0, "duration": XXXX, "type": "http", "span_id": "XXXX"}]]}
88
END RequestId: XXXX
99
REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB Init Duration: XXXX ms
1010
START RequestId: XXXX Version: $LATEST
1111
{"e": XXXX, "m": "aws.lambda.enhanced.invocations", "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python27", "resource:integration-tests-python-XXXX-async-metrics_python27", "cold_start:false", "memorysize:1024", "runtime:python2.7", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python27_X.X.X"], "v": 1}
1212
{"e": XXXX, "m": "hello.dog", "t": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python27_X.X.X"], "v": 1}
1313
{"e": XXXX, "m": "tests.integration.count", "t": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python27_X.X.X"], "v": 21}
14-
HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/2.25.1", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {}
15-
HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/2.25.1", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {}
14+
HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {}
15+
HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {}
1616
{"traces": [[{"resource": "integration-tests-python-XXXX-async-metrics_python27", "name": "aws.lambda", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_sampling_priority_v1": 1, "system.pid": XXXX, "_dd.agent_psr": 1.0}, "parent_id": "XXXX", "meta": {"runtime-id": "XXXX", "request_id": "XXXX", "function_trigger.event_source": "sns", "cold_start": "false", "datadog_lambda": "X.X.X", "function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-async-metrics_python27", "dd_trace": "X.X.X", "_dd.origin": "lambda", "resource_names": "integration-tests-python-XXXX-async-metrics_python27", "function_trigger.event_source_arn": "arn:aws:sns:us-east-2:123456789012:sns-lambda", "function_version": "$LATEST"}, "error": 0, "duration": XXXX, "type": "serverless", "span_id": "XXXX"}, {"resource": "requests.request", "name": "requests.request", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_dd.measured": 1}, "parent_id": "XXXX", "meta": {"http.status_code": "200", "http.url": "https://httpstat.us/200/", "_dd.origin": "lambda", "http.method": "GET"}, "error": 0, "duration": XXXX, "type": "http", "span_id": "XXXX"}, {"resource": "requests.request", "name": "requests.request", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_dd.measured": 1}, "parent_id": "XXXX", "meta": {"http.status_code": "400", "http.url": "https://httpstat.us/400/", "_dd.origin": "lambda", "http.method": "GET"}, "error": 0, "duration": XXXX, "type": "http", "span_id": "XXXX"}]]}
1717
END RequestId: XXXX
1818
REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB
1919
START RequestId: XXXX Version: $LATEST
2020
{"e": XXXX, "m": "aws.lambda.enhanced.invocations", "t": ["region:sa-east-1", "account_id:XXXX", "functionname:integration-tests-python-XXXX-async-metrics_python27", "resource:integration-tests-python-XXXX-async-metrics_python27", "cold_start:false", "memorysize:1024", "runtime:python2.7", "datadog_lambda:vXX", "dd_lambda_layer:datadog-python27_X.X.X"], "v": 1}
2121
{"e": XXXX, "m": "hello.dog", "t": ["team:serverless", "role:hello", "dd_lambda_layer:datadog-python27_X.X.X"], "v": 1}
2222
{"e": XXXX, "m": "tests.integration.count", "t": ["test:integration", "role:hello", "dd_lambda_layer:datadog-python27_X.X.X"], "v": 21}
23-
HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/2.25.1", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {}
24-
HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/2.25.1", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {}
23+
HTTP GET https://httpstat.us/200/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {}
24+
HTTP GET https://httpstat.us/400/ Headers: ["Accept-Encoding:gzip, deflate", "Accept:*/*", "Connection:keep-alive", "User-Agent:python-requests/X.X.X", "x-datadog-parent-id:XXXX", "x-datadog-sampling-priority:1", "x-datadog-trace-id:XXXX"] Data: {}
2525
{"traces": [[{"resource": "integration-tests-python-XXXX-async-metrics_python27", "name": "aws.lambda", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_sampling_priority_v1": 1}, "parent_id": "XXXX", "meta": {"function_arn": "arn:aws:lambda:sa-east-1:601427279990:function:integration-tests-python-XXXX-async-metrics_python27", "request_id": "XXXX", "function_trigger.event_source": "sqs", "cold_start": "false", "datadog_lambda": "X.X.X", "dd_trace": "X.X.X", "_dd.origin": "lambda", "resource_names": "integration-tests-python-XXXX-async-metrics_python27", "function_trigger.event_source_arn": "arn:aws:sqs:us-east-2:123456789012:my-queue", "function_version": "$LATEST"}, "error": 0, "duration": XXXX, "type": "serverless", "span_id": "XXXX"}, {"resource": "requests.request", "name": "requests.request", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_dd.measured": 1}, "parent_id": "XXXX", "meta": {"http.status_code": "200", "http.url": "https://httpstat.us/200/", "_dd.origin": "lambda", "http.method": "GET"}, "error": 0, "duration": XXXX, "type": "http", "span_id": "XXXX"}, {"resource": "requests.request", "name": "requests.request", "service": "aws.lambda", "start": XXXX, "trace_id": "XXXX", "metrics": {"_dd.measured": 1}, "parent_id": "XXXX", "meta": {"http.status_code": "400", "http.url": "https://httpstat.us/400/", "_dd.origin": "lambda", "http.method": "GET"}, "error": 0, "duration": XXXX, "type": "http", "span_id": "XXXX"}]]}
2626
END RequestId: XXXX
2727
REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB

0 commit comments

Comments
 (0)