Isolar sessões de agente hospedado para cada usuário

Um único agente hospedado atende muitos usuários por meio de um único endpoint. Este artigo mostra como o Microsoft Foundry mantém as sessões, conversas e dados armazenados de cada usuário privadas e como estender esse isolamento aos usuários de seu próprio aplicativo. No final, você pode invocar um agente e confirmar que um chamador não pode ver sessões, conversas ou dados armazenados de outro chamador.

Pré-requisitos

Importante

As funções RBAC do Foundry foram renomeadas recentemente. Foundry User, Foundry Owner, Foundry Account Owner e Foundry Project Manager eram anteriormente chamados de Usuário do Azure AI, Proprietário do Azure AI, Proprietário da conta do Azure AI e Gerente de Projeto do Azure AI. Você ainda pode ver os nomes anteriores em alguns lugares enquanto essa mudança de nome está sendo implementada. Os IDs das funções e as permissões principais não são alterados com a mudança de nome.

Entenda o isolamento por usuário

A plataforma identifica cada solicitante pelo seu token do Microsoft Entra e mantém seus dados privados vinculados a essa identidade, embora todos acessem o mesmo agente por meio de um endpoint compartilhado. Para cada usuário, o seguinte permanece isolado:

  • Conversações. O histórico de conversas de cada usuário — as mensagens, chamadas de ferramenta e respostas que ele encadeia por meio do protocolo Responses — é privado e acessível apenas a esse usuário. Um usuário não pode ler ou listar as conversas de outro usuário.
  • Sessões. Cada chamador obtém sua própria sessão por padrão, de modo que as sessões que um usuário pode listar e gerenciar não incluem sessões de outro usuário.
  • Dados armazenados. Os dados que seu agente armazena para um usuário têm como escopo esse usuário, portanto, não são retornados para um usuário diferente.

Pense nisso como um agente atendendo a vários espaços de trabalho privados. Cada sessão também tem seu próprio sistema de arquivos $HOME privado em sua própria sandbox, isolado por padrão, já que cada usuário tem sua própria sessão. Se, em vez disso, você colocar vários usuários na mesma sessão, esse sandbox será compartilhado — consulte Hospedar vários usuários em uma única sessão de agente hospedado. Para obter mais informações sobre o modelo de sessão, consulte Agentes hospedados no Serviço do Agente do Foundry.

Os cenários comuns são:

  • Chat por usuário. Cada cliente conectado obtém seu próprio histórico de conversas, sessões e dados armazenados.
  • Aplicativos multilocatário. Os usuários de cada locatário são isolados dos usuários de todos os outros locatários.

Você obtém esse isolamento por padrão. As seções a seguir mostram o caminho padrão e, em seguida, como estendê-lo aos usuários que você mesmo autentica.

Invocar um agente com isolamento automático

Invoque o agente como a identidade de entrada no serviço. A plataforma cria uma sessão com escopo para essa identidade e retorna sua respectiva agent_session_id.

azd ai agent invoke "Summarize the latest support tickets"

A sessão pertence à identidade de azd auth login. Um usuário conectado diferente que executa o mesmo comando obtém uma sessão privada separada.

Configure as variáveis compartilhadas que os exemplos REST usam:

BASE_URL="https://my-account.services.ai.azure.com/api/projects/my-project"
API_VERSION="v1"
RESOURCE="https://ai.azure.com"
AGENT_NAME="my-agent"

az rest --method POST \
    --url "${BASE_URL}/agents/${AGENT_NAME}/endpoint/protocols/openai/responses?api-version=${API_VERSION}" \
    --resource "${RESOURCE}" \
    --body '{
        "input": "Summarize the latest support tickets",
        "stream": false
    }'

O token do Microsoft Entra na requisição identifica o chamador. O payload da resposta inclui agent_session_id que a plataforma criou e dimensionou essa identidade.

openai_client = project.get_openai_client(agent_name="my-agent")

response = openai_client.responses.create(
    input="Summarize the latest support tickets",
)
session_id = response.model_extra.get("agent_session_id")
print(f"Session: {session_id}")

O cliente OpenAI é autenticado com a credencial de Microsoft Entra do chamador, portanto, a sessão tem como escopo essa identidade.

const openAIClient = project.getOpenAIClient({
    azureConfig: { allowPreview: true, agentName: "my-agent" },
});

const response = await openAIClient.responses.create({
    input: "Summarize the latest support tickets",
});
const sessionId = (response as any).agent_session_id;
console.log(`Session: ${sessionId}`);

O cliente OpenAI é autenticado com a credencial de Microsoft Entra do chamador, portanto, a sessão tem como escopo essa identidade.

Isolar sessões para seus próprios usuários

Se seu aplicativo autenticar seus próprios usuários finais - por exemplo, por meio do Google, GitHub ou um provedor de identidade personalizado - um serviço confiável poderá informar ao Foundry a qual usuário final uma solicitação pertence, de modo que a plataforma isole sessões por usuário final em vez de por serviço de chamada.

O serviço envia o identificador estável do usuário final no x-ms-user-identity cabeçalho. A plataforma trata o valor como uma cadeia de caracteres opaca e define o escopo da sessão para ela. O valor deve ser de 1 a 256 caracteres e conter apenas letras, dígitos e caracteres . _ : - @; outros valores são rejeitados.

Para passar x-ms-user-identity, a identidade de chamada deve ter a permissão Microsoft.CognitiveServices/accounts/AIServices/agents/endpoints/UserIdentityImpersonation/action sobre o agente. Essa permissão não está incluída em nenhuma função integrada. Anteriormente, isso era coberto pela ação de dados Microsoft.CognitiveServices/*, mas essa ação não o concede mais. Conceda-a explicitamente criando uma função personalizada que inclui a ação de dados e atribuindo essa função à identidade do serviço de camada intermediária. Um chamador sem isso recebe um 403. Para obter a definição de função personalizada e os comandos de atribuição, consulte Delegar a identidade do usuário final.

Se um serviço tiver essa permissão, mas não enviar o cabeçalho em uma solicitação, a plataforma definirá o escopo dessa sessão para a própria identidade do serviço em vez de um usuário final. Seu serviço pode misturar chamadas delegadas e não delegadas, mas somente as solicitações que incluem x-ms-user-identity são isoladas por usuário final.

Aviso

No contexto da delegação, a plataforma não isola um usuário final delegado de outro. Ela impõe uma separação rígida apenas entre usuários delegados e não delegados – permitindo que qualquer um dos usuários delegados entre em uma sessão criada pelo aplicativo. Forneça a cada usuário sua própria ID de sessão; se você rotear dois usuários para a mesma sessão, eles poderão ver os dados uns dos outros. Para compartilhar intencionalmente uma única sessão, consulte Multiplexar vários usuários em uma sessão de agente hospedada.

az rest --method POST \
    --url "${BASE_URL}/agents/${AGENT_NAME}/endpoint/protocols/openai/responses?api-version=${API_VERSION}" \
    --resource "${RESOURCE}" \
    --headers "x-ms-user-identity=<stable-end-user-id>" \
    --body '{
        "input": "Summarize my open tickets",
        "stream": false
    }'

Substitua <stable-end-user-id> pelo identificador que seu serviço atribui ao usuário final conectado, como uma ID de usuário com escopo de locatário.

openai_client = project.get_openai_client(agent_name="my-agent")

response = openai_client.responses.create(
    input="Summarize my open tickets",
    extra_headers={"x-ms-user-identity": "<stable-end-user-id>"},
)

Substitua <stable-end-user-id> pelo identificador que seu serviço atribui ao usuário final conectado. A sessão está vinculada a esse usuário final, e não ao serviço chamador.

const openAIClient = project.getOpenAIClient({
    azureConfig: { allowPreview: true, agentName: "my-agent" },
});

const response = await openAIClient.responses.create(
    { input: "Summarize my open tickets" },
    { headers: { "x-ms-user-identity": "<stable-end-user-id>" } },
);
console.log(response.output_text);

Substitua <stable-end-user-id> pelo identificador que seu serviço atribui ao usuário final conectado. A sessão está vinculada a esse usuário final, e não ao serviço chamador.

A CLI do Azure para Desenvolvedores invoca o agente usando sua própria identidade conectada, portanto não transmite uma identidade delegada de usuário final. Use o caminho REST ou SDK do serviço para enviar x-ms-user-identity.

Proteger a identidade do usuário final

Quando você usa o isolamento delegado, seu serviço é o limite de confiança. Escolha identificadores estáveis por usuário, exclusivos e difíceis de adivinhar. Reutilize o mesmo valor para o mesmo usuário para que suas sessões retomem corretamente.

Importante

Derive o valor x-ms-user-identity de uma identidade autenticada no lado do servidor — nunca de um valor que o navegador ou o cliente informa diretamente. Caso contrário, um solicitante pode definir o cabeçalho com o identificador de outro usuário e ler os dados desse usuário. Qualquer serviço com a permissão de delegação pode agir em nome de qualquer usuário final, portanto, conceda-o somente aos serviços de sua confiança.

Verificar isolamento

Confirme se duas identidades recebem duas sessões separadas:

  1. Invoque o agente como uma identidade e anote o agent_session_id retornado.
  2. Invoque o agente usando uma segunda identidade – outro usuário conectado ou um valor x-ms-user-identity diferente – e anote o respectivo agent_session_id.
  3. Confirme se as duas IDs são diferentes e se, ao listar as sessões de cada identidade, são retornadas apenas as sessões dessa própria identidade.

Para ver o isolamento de ponta a ponta, implante o exemplo de agente de anotação, que armazena anotações por sessão em $HOME: as anotações de cada identidade chegam em um arquivo de sessão separado que somente essa identidade pode listar ou baixar por meio da API de Arquivos de Sessão.

Exibir sessões entre usuários

Por padrão, cada chamador vê apenas suas próprias sessões. Um administrador ou automação que detém a função de Usuário do Foundry no projeto pode listar e gerenciar cada sessão no agente, independentemente de qual identidade a criou. Para gerenciar sessões, consulte Gerenciar sessões de agente hospedado.

Chaves de isolamento do protocolo de contêiner 1.0.0 (obsoleto)

Os agentes que usam a versão 1.0.0 do protocolo de contêiner usam o modelo anterior de chave de isolamento, no qual o chamador fornece uma chave de isolamento para delimitar as sessões, em vez de a plataforma derivar a identidade do token do Microsoft Entra. Esse modelo – e o protocolo 1.0.0 propriamente dito – foi preterido. Os agentes no protocolo 1.0.0 continuam funcionando até 31 de julho de 2026; posteriormente, a plataforma bloqueia solicitações para agentes que ainda são executados no protocolo 1.0.0.

Atualize para o protocolo 2.0.0 para obter o isolamento automático por usuário descrito anteriormente neste artigo. O protocolo 2.0.0 requer o SDK do AgentServer que dá suporte a ele - azure-ai-agentserver-core 2.0.0b7 ou posterior para Python ou Azure.AI.AgentServer.Core 1.0.0-beta.26 ou posterior para .NET. Versões anteriores usam o protocolo 1.0.0; atualize-os como parte da atualização.

Solucionar problemas de isolamento

Sintoma Causa provável O que testar
403 ou session_not_accessible ao acessar uma sessão A sessão pertence a uma identidade diferente. Use a mesma identidade que criou a sessão ou mantenha a função De usuário do Foundry para ver as sessões de outras identidades.
403 em uma solicitação que define x-ms-user-identity O chamador não tem a permissão UserIdentityImpersonation, que não é mais concedida por funções internas. Crie uma função personalizada que inclua a ação Microsoft.CognitiveServices/accounts/AIServices/agents/endpoints/UserIdentityImpersonation/action de dados e atribua-a ao serviço de chamada.
As execuções locais não isolam as sessões As execuções locais não impõem isolamento. Teste o isolamento em relação a um agente implantado. O modo local (--local, azd ai agent run) tem como destino um único usuário.