A fully managed platform in Microsoft Foundry for hosting, scaling, and securing AI agents built with any supported framework or model
Your investigation is correct: when the memory tool is configured with scope="{{$userId}}", the placeholder is resolved server-side. The client does not replace it locally.
The current Foundry Memory documentation now describes the resolution rule explicitly:
- If the request contains
x-memory-user-id, that header value is used as the user scope.
If the header is not present, Foundry falls back to the caller's Microsoft Entra identity, represented as:
{tenant-id}_{object-id}
So if your response call is authenticated directly as your Entra user and you are not sending x-memory-user-id, the scope you would expect is:
<TID>_<OID>
For an interactive Azure user, you can get the two values with:
az account show --query tenantId -o tsv
az ad signed-in-user show --query id -o tsv
Then combine them with an underscore.
However, there is an important distinction here: this only works if that Entra user is actually the identity used by the response call. If the hosted agent or another service identity is making the call, the OID will be different.
I also could not find a documented API in the current Memory Store surface that lists or reverse-resolves all existing scope keys. The memory APIs still require the caller to provide the scope when listing or searching memories.
Because of that, for application code I would avoid depending on discovering the automatically generated scope after the fact.
A more deterministic approach is to pass your own stable user identifier:
x-memory-user-id: user-123
while keeping the memory tool configured as:
scope="{{$userId}}"
Then user-123 becomes the known memory scope for that request, and you can use the same value when inspecting or querying that user's memories.
So for your current portal-created memories:
If no x-memory-user-id was supplied, verify the actual Entra identity used by the response call and try {tid}_{oid}.
If the portal does not expose which caller identity was used, I don't see a documented lookup endpoint that will recover the resolved key afterward.
For future tests, explicitly pass x-memory-user-id from the client/API so the scope is deterministic and observable.
This also explains why inspecting the literal {{$userId}} in the SDK source did not reveal the final key—the substitution is intentionally performed by the Foundry service, not by the client SDK.
References
Microsoft Foundry — Create and use memory in Foundry Agent Service https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/memory-usage
Microsoft Agent Framework — Microsoft Foundry provider https://learn.microsoft.com/en-us/agent-framework/agents/providers/microsoft-foundry
AI assistance disclosure: I used ChatGPT to help structure this response, and I reviewed the technical guidance against the current Microsoft Foundry Memory and Agent Framework documentation before posting.