fix(code_interpreter): partition session cache by caller key instead of AWS identity - #524
fix(code_interpreter): partition session cache by caller key instead of AWS identity#524yonib05 wants to merge 3 commits into
Conversation
The AgentCoreCodeInterpreter reconnection cache (_session_mapping) was a process-global map keyed only on the user-facing session_name. Two instances configured with different AWS credentials but the same session_name would reconnect to the same cached AWS session. Key the cache per caller identity instead. An isolation key is derived from the configured boto3 session's credentials (falling back to the session object identity, or a shared default when no boto session is supplied), and the module cache is keyed on (isolation_key, session_name). Instances sharing the same identity (the common single-process, single-credential case) still reconnect exactly as before; instances with different credentials no longer reach each other's cached sessions through a shared session_name. Also document that the in-process cache is a performance optimization and not an isolation boundary: it only persists within one process and deployments serving multiple distinct callers must use separate processes and distinct, unguessable session names. Adds regression tests covering per-identity key scoping and that a session cached by one instance is not reachable from an instance with a different identity via the same session_name.
| ) | ||
|
|
||
| def _resolve_isolation_key(self, boto_session: Optional[boto3.Session]) -> str: | ||
| """Derive a rotation-stable cache-scoping key for the configured credentials. |
There was a problem hiding this comment.
This only works as an isolation key between AWS credentials. Services often run with service credentials and need isolation by the callers Session identifier. How can this be made generic, such that other partition keys can be used?
|
Consider the way session_id is used in the SessionManager functionality. |
|
Reworked. The cache is now keyed on Dropped the STS/credential-derived key: one IAM identity serves many callers, so keying on credentials collapsed them. Operators now pass the caller's session id as Re: the warning — the map was never the boundary. Sessions are reachable only via the server-issued unguessable |
Description
AgentCoreCodeInterpreterkeeps a module-level_session_mappingcache so that a new instance in a long-running process can reconnect to an existing AWS code interpreter session instead of recreating it. The cache was keyed only on the user-facingsession_name, which is process-global, so two instances using the samesession_namewould reconnect to the same cached session regardless of who the caller was.This change partitions the cache by an explicit, caller-supplied
partition_key. The cache is keyed on(partition_key, session_name), andpartition_keyis bound at construction from operator-controlled input and is never read from a tool action, so a model-suppliedsession_namecannot reach across partitions.A service typically runs under a single IAM identity while serving many callers, so an AWS-credential-derived key would collapse those callers together. Keying on a caller-supplied partition instead lets one identity host many isolated sessions:
partition_keydefaults to a shared"default"partition, preserving the prior single-caller reconnect behavior.partition_keyper principal — the authenticated principal/tenant id, or the agent session id (e.g.context.session_id) when one identity runs several isolated sessions.The in-process cache is a reconnect convenience, not the isolation boundary. The real boundary is AWS-side: a session is reachable only by holding its server-issued, unguessable
sessionId, and every operation is authorized against the interpreter's IAM execution role. Within a single process,partition_keyis what keeps callers apart.The public tool contract is unchanged: the
session_nameaction field and existing constructor arguments behave as before;partition_keyis a new optional argument.Changes
partition_keyconstructor argument and key_session_mappingon(partition_key, session_name)via the_scoped_keyhelper.partition_keyat construction (default"default"); it is never taken from a tool action.GetCallerIdentityderived key (and its eager call at init); the cache key no longer depends on AWS credentials, so credential rotation cannot cause a reconnect miss.sessionId+ IAM execution role) and describe the cache as a per-process reconnect convenience partitioned bypartition_key.Testing
pytest tests/code_interpreter/passes (59 tests).ruff format/ruff checkclean.partition_keyis the shared"default"partition,session_name,session_name(the multi-tenant case),partition_keyreconnect to the same cached AWS session,