The middleware accepts several configuration options as keyword-only arguments:
`CorrelationIDConfig`
CorrelationIDConfig is the exported immutable configuration object used by
CorrelationIDMiddleware. It is a frozen dataclass, so configuration state is
validated and copied during construction, then exposed as read-only fields.
| Field | Type | Default | Description |
|---|---|---|---|
header_name |
str |
"X-Correlation-ID" |
Header used for incoming and outgoing IDs. |
trusted_sources |
Iterable[str] |
frozenset() |
Trusted IP addresses or CIDR ranges. |
generator |
Callable[[], str] |
default_uuid7_generator |
Callable used when the middleware creates a new ID. |
validator |
callable or None |
None |
Optional validator for incoming trusted IDs. |
echo_header_in_response |
bool |
True |
Whether to copy the resolved ID into the response header during process_response. |
Pass a config object directly to build or share middleware configuration explicitly:
import falcon
from falcon_correlate import CorrelationIDConfig, CorrelationIDMiddleware
config = CorrelationIDConfig(
trusted_sources=["10.0.0.0/8"],
echo_header_in_response=True,
)
middleware = CorrelationIDMiddleware(config=config)
app = falcon.App(middleware=[middleware])
The CorrelationIDConfig.from_kwargs() classmethod mirrors the middleware's
keyword arguments and returns a validated config object. When trusted_sources
is omitted or None, it defaults to an empty frozenset. When generator is
omitted or None, it defaults to default_uuid7_generator.
from falcon_correlate import CorrelationIDConfig, CorrelationIDMiddleware
config = CorrelationIDConfig.from_kwargs(
header_name="X-Request-ID",
trusted_sources=("127.0.0.1",),
)
middleware = CorrelationIDMiddleware(config=config)
The trusted_sources field is always frozen. Regardless of whether a list,
set, tuple, or other iterable is supplied, config.trusted_sources is a
frozenset, and mutations to the original input do not affect the config:
from falcon_correlate import CorrelationIDConfig
sources = ["10.0.0.0/8"]
config = CorrelationIDConfig(trusted_sources=sources)
sources.append("192.168.0.0/16") # mutation has no effect
assert "192.168.0.0/16" not in config.trusted_sources
header_name
The HTTP header name used for incoming and outgoing correlation IDs.
- Type:
str - Default:
"X-Correlation-ID"
middleware = CorrelationIDMiddleware(header_name="X-Request-ID")
trusted_sources
A collection of IP addresses or Classless Inter-Domain Routing (CIDR) subnets considered trusted. Correlation IDs will only be accepted from requests originating from these addresses.
- Type:
Iterable[str] | None - Default:
None(no sources trusted)
Both exact IP addresses and CIDR subnet notation are supported:
middleware = CorrelationIDMiddleware(
trusted_sources=[
"127.0.0.1", # Exact IPv4 address
"10.0.0.0/8", # IPv4 CIDR subnet
"192.168.1.0/24", # Another IPv4 subnet
"::1", # Exact IPv6 address
"2001:db8::/32", # IPv6 CIDR subnet
]
)
Important notes:
- IP addresses and CIDR notations are validated at configuration time. Invalid
formats will raise
ValueError. - CIDR notation must specify network addresses, not host addresses. For example,
10.0.0.0/24is valid, but10.0.0.5/24will raise an error because it has host bits set. - An empty or unspecified
trusted_sourcesmeans no sources are trusted, and all incoming IDs are rejected. New IDs will be generated for every request.
Security note: Only add IP addresses that are fully trusted to propagate correlation IDs. Misconfiguration could allow malicious actors to inject arbitrary IDs.
generator
A callable that generates new correlation IDs. Must take no arguments and return a string.
- Type:
Callable[[], str] | None - Default:
default_uuid7_generator(returns UUIDv7 hex strings viauuid.uuid7()when available, otherwiseuuid-utils)
import uuid
def custom_generator() -> str:
return f"req-{uuid.uuid4().hex[:8]}"
middleware = CorrelationIDMiddleware(generator=custom_generator)
validator
An optional callable that validates incoming correlation IDs during request
processing. Takes a string and returns True if the ID is valid, False
otherwise. When a validator is configured, incoming IDs from trusted sources
are checked before acceptance. Invalid IDs are discarded, a new ID is
generated, and the failure is logged at DEBUG level.
- Type:
Callable[[str], bool] | None - Default:
None(no validation beyond trust checking)
When no validator is configured, incoming IDs from trusted sources are accepted without format checking. This maintains backwards compatibility.
The library provides default_uuid_validator as a ready-to-use validator that
accepts any standard UUID format (versions 1-8), both hyphenated (
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) and hex-only (32 characters). It is
case-insensitive and rejects empty, malformed, or excessively long strings.
from falcon_correlate import CorrelationIDMiddleware, default_uuid_validator
# Use the built-in UUID validator
middleware = CorrelationIDMiddleware(validator=default_uuid_validator)
For custom validation requirements, a custom validator function can be provided:
import re
UUID_PATTERN = re.compile(
r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
re.IGNORECASE,
)
def uuid_validator(value: str) -> bool:
return bool(UUID_PATTERN.match(value))
middleware = CorrelationIDMiddleware(validator=uuid_validator)
Logging note: When an incoming ID fails validation, the middleware logs a
DEBUG-level message. The rejected value is not included in the log to avoid
log injection and privacy risks. To see these messages, configure logging to
capture DEBUG output from the falcon_correlate.middleware logger.