procurement-ingest/lambdas/shared/sentry_init.py

98 lines
2.4 KiB
Python

"""Shared Sentry SDK init for every procurement-ingest Lambda.
Imported for side effect from each handler. ``init_sentry()`` is a no-op when
``SENTRY_DSN`` is unset so pytest, local invokes, and a missing HCP var never
talk to Sentry. ``before_send`` strips auth headers and drops request/extra
keys that can hold MIME bodies, Bedrock prompts, or HMAC secret material.
"""
import os
import sentry_sdk
from sentry_sdk.integrations.aws_lambda import AwsLambdaIntegration
_HEADER_DROP_NAMES = frozenset(
{
"authorization",
"x-auth-token",
"cookie",
"x-amz-security-token",
}
)
_DROP_REQUEST_KEYS = frozenset(
{
"body",
"Body",
"data",
"cookies",
"raw_email",
"prompt",
"secret",
"SecretString",
"hmac",
"keys",
}
)
_DROP_EXTRA_NEEDLES = (
"body",
"email",
"prompt",
"secret",
"hmac",
"token",
"mime",
"raw_email",
)
def _drop_header(name):
lower = str(name).lower()
return lower in _HEADER_DROP_NAMES or lower.startswith("x-amz-")
def _scrub_headers(headers):
if isinstance(headers, dict):
return {k: v for k, v in headers.items() if not _drop_header(k)}
if isinstance(headers, list):
kept = []
for pair in headers:
if isinstance(pair, (list, tuple)) and pair and _drop_header(pair[0]):
continue
kept.append(pair)
return kept
return headers
def _before_send(event, _hint):
request = event.get("request")
if isinstance(request, dict):
headers = request.get("headers")
if headers is not None:
request["headers"] = _scrub_headers(headers)
for key in list(request):
if key in _DROP_REQUEST_KEYS or str(key).lower() in {"body", "data"}:
request.pop(key, None)
extra = event.get("extra")
if isinstance(extra, dict):
for key in list(extra):
lower = str(key).lower()
if any(needle in lower for needle in _DROP_EXTRA_NEEDLES):
extra.pop(key, None)
return event
def init_sentry():
dsn = os.environ.get("SENTRY_DSN")
if not dsn:
return
sentry_sdk.init(
dsn=dsn,
integrations=[AwsLambdaIntegration(timeout_warning=True)],
send_default_pii=False,
enable_logs=False,
traces_sample_rate=0.0,
before_send=_before_send,
)
init_sentry()