Summary
We are pleased to announce our first security feature: Data Masking. You can now encrypt, decrypt, or irreversibly erase sensitive information to protect data confidentiality.
We also made enhancements to our OpenAPI utility, and fixed some bugs!
⭐ Huge thanks to our new contributor: @maauk
Data masking
You can now encrypt, decrypt, or irreversibly erase sensitive information to protect data confidentiality.
We partnered with the AWS Crypto team to offer a thin layer on top of the AWS Encryption SDK and Amazon KMS, optimized to run on AWS Lambda ephemeral environments.
At launch, Data Masking solves three common use cases, with a fourth one (field encryption) coming.
- Selectively erase confidential data. You want to remove sensitive information from one or more fields for a given payload, however nested these fields might be.
- Encrypt and decrypt an entire payload. You want to protect the entire payload while ensuring data integrity, and optionally add metadata to each operation for further protection.
- Use multiple keys for high availability. You want to use more than one Amazon KMS key to encrypt while allowing decryption with any of the keys used for encryption.
It wouldn't be awesome if we didn't mention that we spent a few months crafting several code snippets, use cases, diagrams, and a simplified terminology to help you digest common industry security practices.
Enough with the talk :) Here's a working code snippet with these use cases combined.
from __future__ import annotations
import os
from aws_lambda_powertools import Logger
from aws_lambda_powertools.utilities.data_masking import DataMasking
from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import (
AWSEncryptionSDKProvider,
)
from aws_lambda_powertools.utilities.typing import LambdaContext
KEY_ONE = os.getenv("KMS_KEY_ARN", "")
KEY_TWO = os.getenv("KMS_KEY_TWO_ARN", "")
logger = Logger()
encryption_provider = AWSEncryptionSDKProvider(keys=[KEY_ONE, KEY_TWO]) # encrypt/decrypt operations
data_masker = DataMasking(provider=encryption_provider)
@logger.inject_lambda_context
def lambda_handler(event: dict, context: LambdaContext) -> dict:
data: dict = event.get("body", {})
logger.info("Erasing fields email, address.street, and company_address")
erased: dict = data_masker.erase(data, fields=["email", "address.street", "company_address"]) # values become '*****'
# tenant_id being optional metadata that must match in decrypt for further protection
encrypted: str = data_masker.encrypt(data, tenant_id=event.get("tenant_id", ""))
decrypted: dict = data_masker.decrypt(data, tenant_id=event.get("tenant_id", ""))
return erased
⭐⭐ Huge thanks to @seshubaws for the extensive work on this feature!
Header parameter validation in OpenAPI schema
Our enhanced OpenAPI utility now enables you to seamlessly incorporate headers into your API specifications.
from typing import List
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.event_handler.openapi.params import Header
from aws_lambda_powertools.shared.types import Annotated
from aws_lambda_powertools.utilities.typing import LambdaContext
app = APIGatewayRestResolver(enable_validation=True)
@app.get("/hello")
def get_hello(header2: Annotated[List[str], Header()], header1: Annotated[str, Header()]):
print(header2)
def lambda_handler(event: dict, context: LambdaContext) -> dict:
return app.resolve(event, context)
Changes
- fix(data-masking): fix and improve e2e tests for DataMasking (#3695) by @leandrodamascena
- fix(event-handler): strip whitespace from Content-Type headers during OpenAPI schema validation (#3677) by @leandrodamascena
📜 Documentation updates
- feat(event_handler): support Header parameter validation in OpenAPI schema (#3687) by @leandrodamascena
- docs(data-masking): add docs for data masking utility (#3186) by @seshubaws
- docs(proccess): add versioning and maintenance policy (#3682) by @leandrodamascena
- chore(deps): bump squidfunk/mkdocs-material from
9aad7af
toa4a2029
in /docs (#3679) by @dependabot - chore(deps): bump squidfunk/mkdocs-material from
58eef6c
to9aad7af
in /docs (#3670) by @dependabot - feat(event_handler): add support for multiValueQueryStringParameters in OpenAPI schema (#3667) by @leandrodamascena
- docs(metrics): fix empty metric warning filter (#3660) by @maauk
🔧 Maintenance
- chore(deps-dev): bump aws-cdk from 2.124.0 to 2.125.0 (#3693) by @dependabot
- docs(data-masking): add docs for data masking utility (#3186) by @seshubaws
- chore(deps-dev): bump ruff from 0.1.14 to 0.1.15 (#3685) by @dependabot
- chore(deps-dev): bump sentry-sdk from 1.39.2 to 1.40.0 (#3684) by @dependabot
- chore(deps): bump codecov/codecov-action from 3.1.5 to 3.1.6 (#3683) by @dependabot
- chore(deps-dev): bump aws-cdk from 2.123.0 to 2.124.0 (#3678) by @dependabot
- chore(deps): bump squidfunk/mkdocs-material from
9aad7af
toa4a2029
in /docs (#3679) by @dependabot - chore(deps): bump codecov/codecov-action from 3.1.4 to 3.1.5 (#3674) by @dependabot
- chore(deps-dev): bump aws-cdk from 2.122.0 to 2.123.0 (#3673) by @dependabot
- chore(deps): bump squidfunk/mkdocs-material from
58eef6c
to9aad7af
in /docs (#3670) by @dependabot - chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update (#3665) by @dependabot
- chore(deps-dev): bump ruff from 0.1.13 to 0.1.14 (#3656) by @dependabot
- chore(deps): bump pydantic from 1.10.13 to 1.10.14 (#3655) by @dependabot
This release was made possible by the following contributors:
@dependabot, @dependabot[bot], @github-actions, @github-actions[bot], @leandrodamascena, @maauk and @seshubaws