Storage: Environment variables (loaded at runtime),
HTTP request headers (in transit)
Access: SDK client code
(libs/sdk-py/langgraph_sdk/_shared/utilities.py:_get_api_key),
any process with env var access
Encryption: TLS in transit (if HTTPS); no at-rest
encryption for env vars
Retention: Session/process lifetime
Logging exposure: API key stripped of quotes but
could appear in debug logs if HTTP headers are logged.
RESERVED_HEADERS prevents user override of
x-api-key but doesn’t prevent logging.
Cross-border: Travels with every HTTP request to
the LangGraph Server
Gaps: SDK request_reconnect() and
stream() forward x-api-key header to
server-controlled Location redirect URLs without URL
validation (see T9)
Gaps: Key loaded from env var as UTF-8 string
limits entropy to ~6.57 bits/byte (see T7). Cipher name validated with
assert which is stripped by python -O (see
T8).
DC3: Serialized Graph State
Fields: All channel values serialized via
JsonPlusSerializer.dumps_typed() — includes complete agent
state, conversation history, tool call results, and any user-defined
state
Access: Any code with database credentials;
BaseCheckpointSaver.get_tuple() / put()
Encryption: Optional via
EncryptedSerializer wrapping (AES-EAX) or SDK Encryption
Handlers (beta, server-side). Not encrypted by default.
Retention: Unbounded by default. Optional TTL via
CheckpointerConfig.ttl (server-side config)
Logging exposure: Serde event hooks emit
module/class names of deserialized types but not the data itself
Gaps: Default unbounded retention of potentially
PII-containing state. Unencrypted by default. EncryptedSerializer has
fallback that accepts unencrypted data (see T10).
Storage: Same as DC3 (within serialized checkpoint
data)
Access: Same as DC3
Encryption: Only if DC3 is encrypted via
EncryptedSerializer or SDK Encryption Handlers
Retention: Same as DC3 (unbounded default)
Gaps: Conversation content may include user PII,
PHI, or sensitive business data. No field-level encryption or redaction.
Retention inherits from DC3 with no conversation-specific policy.
Encryption: N/A — this is context for encryption,
not encrypted data itself
Retention: Persisted with encrypted data
indefinitely
Logging exposure: Not logged by SDK code
Gaps: metadata is a mutable dict —
whether cross-request isolation is enforced depends on server-side
implementation (langgraph-api, out of scope). ContextHandler
registration at
libs/sdk-py/langgraph_sdk/encryption/__init__.py:Encryption.context
does not call _validate_handler (missing async/param-count
validation, unlike all other handler types).