{"meta":{"title":"Multilocação e implantações de servidores","intro":"O modo de servidor multiusuário significa executar o SDK do Copilot a partir de um código de back-end que atende a mais de um usuário, locatário, workspace ou conta de integração. Nessa configuração, o aplicativo é responsável pelo roteamento das solicitações e pela autorização, enquanto o SDK e o runtime fornecem estado por sessão, autenticação por sessão e registro explícito de ferramentas, para que a sessão de um usuário não herde as ferramentas nem a identidade de outro usuário.","product":"GitHub Copilot","breadcrumbs":[{"href":"/pt/enterprise-cloud@latest/copilot","title":"GitHub Copilot"},{"href":"/pt/enterprise-cloud@latest/copilot/how-tos","title":"Instruções"},{"href":"/pt/enterprise-cloud@latest/copilot/how-tos/copilot-sdk","title":"SDK do Copilot"},{"href":"/pt/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/setup","title":"Configurar o SDK do Copilot"},{"href":"/pt/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/setup/multi-tenancy","title":"Multilocação"}],"documentType":"article"},"body":"# Multilocação e implantações de servidores\n\nO modo de servidor multiusuário significa executar o SDK do Copilot a partir de um código de back-end que atende a mais de um usuário, locatário, workspace ou conta de integração. Nessa configuração, o aplicativo é responsável pelo roteamento das solicitações e pela autorização, enquanto o SDK e o runtime fornecem estado por sessão, autenticação por sessão e registro explícito de ferramentas, para que a sessão de um usuário não herde as ferramentas nem a identidade de outro usuário.\n\n<!-- markdownlint-disable GHD046 GHD005 -->\n\n<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->\n\n**Melhor para:** Produtos saaS, integrações de parceiros, plataformas internas e serviços de back-end que lidam com usuários simultâneos.\n\n## Use este guia quando\n\nUse este guia ao criar:\n\n* Um produto SaaS multiusuário que incorpora agentes com tecnologia Copilot\n* Um back-end para uma integração com parceiros, como um padrão no estilo do Copilot Studio ou do Fabric\n* Qualquer servidor que gerencia usuários simultâneos, espaços de trabalho, tenants ou solicitações\n* Um runtime compartilhado no qual vários clientes do SDK se conectam a um processo de runtime do Copilot\n\nEste guia é um guia complementar a [Escalabilidade e multitenância](/pt/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/setup/scaling). Use esse guia para topologia, balanceamento de carga e padrões de armazenamento. Use este guia para opções no nível do SDK e opções de isolamento de runtime.\n\n## Principais opções do SDK\n\n| Opção                           | Use-o para                                                                                   | Observações                                                            |\n| ------------------------------- | -------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |\n| `mode: \"empty\"`                 | Desativação das ferramentas nativas do sistema operacional e das configurações padrão da CLI | Necessário para cenários compartilhados ou multiusuários.              |\n| `sessionIdleTimeoutSeconds`     | Limpar sessões ociosas                                                                       | Defina um timeout no lado do servidor para processos de longa duração. |\n| `baseDirectory`                 | Isolando `COPILOT_HOME` por instância de runtime                                             | Ignorado ao se conectar a um runtime existente.                        |\n| `sessionFs`                     | Encaminhamento do armazenamento do sistema de arquivos da sessão para fora do disco local    | Emparelhe com provedores de sistema de arquivos por sessão.            |\n| `RuntimeConnection.forUri(url)` | Compartilhando um runtime já em execução                                                     | Os nomes de idioma variam; veja os exemplos abaixo.                    |\n| Por sessão `gitHubToken`        | Autenticação com escopo para o usuário solicitante.                                          | Prefira isso em vez de um único token de usuário compartilhado.        |\n\n### `mode: \"empty\"`\n\n`mode: \"empty\"` desabilita o comportamento opcional da CLI Copilot por padrão. No modo de servidor multiusuário, essa é a linha de base segura porque seu aplicativo deve decidir explicitamente quais ferramentas, servidores MCP, habilidades e caminhos de workspace uma sessão pode acessar.\n\nNão use o padrão `mode: \"copilot-cli\"` para servidores compartilhados. Esse modo destina-se a agentes de programação do tipo CLI e pode expor capacidades do sistema de arquivos do host no ambiente.\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n```typescript\nimport { CopilotClient, RuntimeConnection } from \"@github/copilot-sdk\";\n\n// baseDirectory and sessionIdleTimeoutSeconds apply when the SDK spawns the\n// runtime. With RuntimeConnection.forUri(...) configure COPILOT_HOME and the\n// idle timeout on the runtime process itself.\nconst client = new CopilotClient({\n    mode: \"empty\",\n    connection: RuntimeConnection.forUri(process.env.COPILOT_RUNTIME_URL!),\n});\n\nconst session = await client.createSession({\n    sessionId: `user-${user.id}-${crypto.randomUUID()}`,\n    model: \"gpt-5.4\",\n    availableTools: [\"custom:lookupOrder\", \"custom:createTicket\"],\n    gitHubToken: user.githubToken,\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n```python\nfrom copilot import CopilotClient, RuntimeConnection\nfrom copilot.session import PermissionHandler\n\nclient = CopilotClient(\n    mode=\"empty\",\n    base_directory=f\"/var/lib/my-app/copilot/{runtime_instance_id}\",\n    session_idle_timeout_seconds=900,\n    connection=RuntimeConnection.for_uri(runtime_url),\n)\nawait client.start()\n\nsession = await client.create_session(\n    session_id=f\"user-{user.id}-{request_id}\",\n    model=\"gpt-5.4\",\n    available_tools=[\"custom:lookupOrder\", \"custom:createTicket\"],\n    github_token=user.github_token,\n    on_permission_request=PermissionHandler.approve_all,\n)\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"go\" data-label=\"Go\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Go</div>\n\n```golang\nclient := copilot.NewClient(&copilot.ClientOptions{\n    Mode:                      copilot.ModeEmpty,\n    BaseDirectory:             fmt.Sprintf(\"/var/lib/my-app/copilot/%s\", runtimeInstanceID),\n    SessionIdleTimeoutSeconds: 900,\n    Connection:                copilot.URIConnection{URL: runtimeURL},\n})\n\nsession, err := client.CreateSession(ctx, &copilot.SessionConfig{\n    SessionID:      fmt.Sprintf(\"user-%s-%s\", user.ID, requestID),\n    Model:          \"gpt-5.4\",\n    AvailableTools: []string{\"custom:lookupOrder\", \"custom:createTicket\"},\n    GitHubToken:    user.GitHubToken,\n})\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"dotnet\" data-label=\".NET\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">.NET</div>\n\n```csharp\nvar client = new CopilotClient(new CopilotClientOptions\n{\n    Mode = CopilotClientMode.Empty,\n    BaseDirectory = $\"/var/lib/my-app/copilot/{runtimeInstanceId}\",\n    SessionIdleTimeoutSeconds = 900,\n    Connection = RuntimeConnection.ForUri(runtimeUrl),\n});\n\nawait using var session = await client.CreateSessionAsync(new SessionConfig\n{\n    SessionId = $\"user-{user.Id}-{requestId}\",\n    Model = \"gpt-5.4\",\n    AvailableTools = [\"custom:lookupOrder\", \"custom:createTicket\"],\n    GitHubToken = user.GitHubToken,\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"java\" data-label=\"Java\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Java</div>\n\n```java\n// setCopilotHome and setSessionIdleTimeoutSeconds are ignored when\n// setCliUrl is used; configure those on the runtime process instead.\nvar client = new CopilotClient(new CopilotClientOptions()\n    .setMode(CopilotClientMode.EMPTY)\n    .setCliUrl(runtimeUrl)\n);\n\nvar session = client.createSession(new SessionConfig()\n    .setSessionId(\"user-\" + user.id() + \"-\" + requestId)\n    .setModel(\"gpt-5.4\")\n    .setAvailableTools(List.of(\"custom:lookupOrder\", \"custom:createTicket\"))\n    .setGitHubToken(user.gitHubToken())\n).get();\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"rust\" data-label=\"Rust\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Rust</div>\n\n```rust\nuse std::path::PathBuf;\nuse github_copilot_sdk::{Client, ClientOptions, Transport};\nuse github_copilot_sdk::mode::ClientMode;\nuse github_copilot_sdk::types::SessionConfig;\n\nlet client = Client::start(\n    ClientOptions::new()\n        .with_mode(ClientMode::Empty)\n        .with_base_directory(PathBuf::from(format!(\n            \"/var/lib/my-app/copilot/{runtime_instance_id}\"\n        )))\n        .with_session_idle_timeout_seconds(900)\n        .with_transport(Transport::External {\n            host: runtime_host.to_string(),\n            port: runtime_port,\n            connection_token: None,\n        }),\n).await?;\n\nlet session = client.create_session(\n    SessionConfig::default()\n        .with_session_id(format!(\"user-{}-{request_id}\", user.id))\n        .with_model(\"gpt-5.4\")\n        .with_available_tools([\"custom:lookupOrder\", \"custom:createTicket\"])\n        .with_github_token(user.github_token),\n).await?;\n```\n\n</div>\n\n</div>\n\n### `sessionIdleTimeoutSeconds`\n\nDefina `sessionIdleTimeoutSeconds` em servidores para que as sessões inativas sejam limpas automaticamente. Isso impede sessões zumbis em processos de execução longa e reduz a pressão de memória e sistema de arquivos.\n\n| Linguagem  | Opção pública                            |\n| ---------- | ---------------------------------------- |\n| TypeScript | `sessionIdleTimeoutSeconds`              |\n| Python     | `session_idle_timeout_seconds`           |\n| Go         | `SessionIdleTimeoutSeconds`              |\n| .NET       | `SessionIdleTimeoutSeconds`              |\n| Java       | `setSessionIdleTimeoutSeconds(...)`      |\n| Rust       | `with_session_idle_timeout_seconds(...)` |\n\nUse um valor que corresponda ao tempo de duração da conversa do seu produto. Para back-ends de chat, 15 a 30 minutos geralmente é um bom ponto de partida. Para agentes de fluxo de trabalho, use um tempo limite maior e uma exclusão explícita quando o fluxo de trabalho for concluído.\n\n### `baseDirectory`\n\n`baseDirectory` define `COPILOT_HOME` para uma instância de runtime. Use para isolar o estado de tempo de execução, credenciais e dados de sessão por processo, pod, worker ou limite de tenant.\n\n```typescript\nconst client = new CopilotClient({\n    mode: \"empty\",\n    baseDirectory: `/var/lib/my-app/copilot/runtime-${process.env.HOSTNAME}`,\n    sessionIdleTimeoutSeconds: 900,\n});\n```\n\nO tempo de execução armazena o estado da sessão no `COPILOT_HOME`, configurado, incluindo `session-state/{sessionId}`. Se o aplicativo executar várias instâncias de runtime, dê a cada instância um diretório distinto, a menos que você use intencionalmente o armazenamento compartilhado.\n\nQuando o SDK se conecta a um runtime já em execução com `RuntimeConnection.forUri(url)`, `baseDirectory` é ignorado pelo cliente do SDK. Configure `COPILOT_HOME` no processo de execução em vez disso.\n\n### `sessionFs`\n\n`sessionFs` registra um provedor personalizado de sistema de arquivos de sessão para que a E/S de arquivos com escopo de sessão possa ser roteada por meio do armazenamento do aplicativo em vez do disco local do ambiente de execução. Use quando o disco local for efêmero, quando o estado da sessão precisar residir no armazenamento de objetos ou quando uma plataforma precisar impor caminhos de armazenamento específicos para cada tenant.\n\n```typescript\nconst client = new CopilotClient({\n    mode: \"empty\",\n    sessionFs: {\n        initialCwd: \"/workspace\",\n        sessionStatePath: \"/session-state\",\n        conventions: \"posix\",\n    },\n});\n```\n\nPara linguagens que expõem um callback do provedor, configure `sessionFs` no nível do cliente e forneça um manipulador do sistema de arquivos para cada sessão ao criar ou retomar uma sessão. Consulte [Retomada e persistência da sessão](/pt/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/features/session-persistence) para obter conceitos de persistência e compensações de armazenamento.\n\nSuperfícies do SDK público verificadas:\n\n| Linguagem                                      | Configuração no nível do cliente | Provedor por sessão.            |\n| ---------------------------------------------- | -------------------------------- | ------------------------------- |\n| TypeScript                                     | `sessionFs`                      |                                 |\n| `createSessionFsAdapter`/callbacks do provedor |                                  |                                 |\n| Python                                         | `session_fs`                     | `create_session_fs_handler`     |\n| Go                                             | `SessionFS`                      | `CreateSessionFSProvider`       |\n| .NET                                           | `SessionFs`                      | `CreateSessionFsProvider`       |\n| Rust                                           | `with_session_fs(...)`           | `with_session_fs_provider(...)` |\n\nJava atualmente não expõe uma opção `sessionFs` pública verificada, portanto, este guia não mostra um exemplo de Java `sessionFs`.\n\n### `RuntimeConnection.forUri(url)`\n\nUse uma conexão de tempo de execução externa quando vários clientes do SDK precisarem compartilhar um tempo de execução já em execução. Isso é comum em serviços de back-end em que o processo de runtime é gerenciado separadamente dos manipuladores de solicitação.\n\n| Linguagem  | Conexão com ambiente de execução externo               |\n| ---------- | ------------------------------------------------------ |\n| TypeScript | `RuntimeConnection.forUri(url)`                        |\n| Python     | `RuntimeConnection.for_uri(url)`                       |\n| Go         | `copilot.URIConnection{URL: url}`                      |\n| .NET       | `RuntimeConnection.ForUri(url)`                        |\n| Java       | `setCliUrl(url)`                                       |\n| Rust       | `Transport::External { host, port, connection_token }` |\n\nOs runtimes externos gerenciam sua própria autenticação e armazenamento em nível de processo. Passe tokens por sessão em `createSession` ou `resumeSession` quando precisar de autenticação específica do usuário.\n\n### Por sessão `gitHubToken`\n\nDefina `gitHubToken` em cada sessão para restringir o escopo da autenticação do GitHub ao usuário solicitante. Isso é diferente de um token no nível do cliente, que autentica o processo de runtime.\n\n```typescript\nconst session = await client.createSession({\n    sessionId: `user-${user.id}-support`,\n    model: \"gpt-5.4\",\n    availableTools: [\"custom:*\"],\n    gitHubToken: user.githubToken,\n});\n```\n\nUse tokens por sessão para exclusão de conteúdo, roteamento de modelos, verificações de cotas e acesso ao Copilot específico do usuário. Evite compartilhar um token de serviço entre usuários, a menos que seu produto use intencionalmente a semântica de conta de serviço.\n\n## ID de integração\n\nOs parceiros que criam agentes de marca podem definir uma ID de integração para solicitações de Controle de Missão. O runtime lê `GITHUB_COPILOT_INTEGRATION_ID` e o define como o cabeçalho HTTP `Copilot-Integration-Id` em cada solicitação do Mission Control.\n\n```bash\nGITHUB_COPILOT_INTEGRATION_ID=my-product-agent copilot --headless --port 4321\n```\n\nA ID de integração padrão é `copilot-developer-cli`. Use um valor estável, como `my-product-agent` para atribuição e roteamento. A ID de integração está configurada apenas por variável de ambiente; não é uma opção de SDK de primeira classe.\n\nSe o SDK gerar o runtime, passe a variável de ambiente pela opção de ambiente do cliente. Se você se conectar com `RuntimeConnection.forUri(url)`, defina a variável de ambiente no próprio processo de tempo de execução.\n\n## Garantias de isolamento em nível de sessão\n\nO isolamento no nível da sessão significa que o runtime mantém as informações de estado e modelo específicas do usuário no escopo de uma sessão, não no estado compartilhado global.\n\n| Superfície                  | Comportamento de isolamento                                                             |\n| --------------------------- | --------------------------------------------------------------------------------------- |\n| Cache de lista de modelos   | Por sessão. A pesquisa de modelo usa o cache de lista de modelos da sessão.             |\n| Estado da sessão            | ID por sessão em `COPILOT_HOME/session-state/{sessionId}`.                              |\n| Identidade do GitHub        | Por sessão, quando `gitHubToken` é definido na sessão.                                  |\n| Tools                       | Explícito em `mode: \"empty\"`; ambiente em `mode: \"copilot-cli\"`.                        |\n| Sistema de arquivos de host | Compartilhado pelo processo de runtime se as ferramentas de host estiverem disponíveis. |\n\n`mode: \"empty\"` é o que torna os padrões de runtime compartilhados viáveis: nenhuma ferramenta de sistema operacional ambiente é exposta, a menos que seu aplicativo registre ou permita. Com `mode: \"copilot-cli\"`, o acesso ao sistema de arquivos do sistema operacional é compartilhado por meio do processo de host, portanto, não use esse modo para o modo de servidor multiusuário.\n\nO estado da sessão é armazenado em `COPILOT_HOME/session-state/{sessionId}`, a menos que você o direcione por `sessionFs`. Use IDs de sessão exclusivas que incluem seu próprio locatário ou limite de usuário e imponha o controle de acesso antes de retomar ou excluir sessões.\n\n## Comparação de padrões\n\n| Pattern                                         | Usar quando                                                                                                                             | Compensações                                                                                                                                                                                  |\n| ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Padrão 1: CLI isolada por usuário               | Você precisa do limite de isolamento mais forte ou das credenciais de processo separadas por usuário.                                   | Isolamento forte; custo de recurso mais alto. Consulte [Escalabilidade e multitenância](/pt/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/setup/scaling).                               |\n| Padrão 2: CLI compartilhada com `mode: \"empty\"` | Você deseja que um runtime atenda a muitos usuários enquanto seu aplicativo controla as ferramentas, a autenticação e as IDs de sessão. | Eficiente; requer um registro cuidadoso de ferramentas, tokens por sessão e verificações de acesso no nível do aplicativo.                                                                    |\n| Padrão 3: híbrido                               | Você roteia o trabalho de computação pesada para sessões de nuvem e trabalho leve para sessões locais.                                  | Flexível; requer o roteamento de carga de trabalho e o tratamento de políticas. Consulte [Sessões de nuvem](/pt/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/features/cloud-sessions). |\n\n### Padrão 2: CLI compartilhada com `mode: \"empty\"`\n\nNesse padrão, todos os usuários se conectam por meio do back-end a um pool de runtime. O aplicativo executa a autenticação do usuário, escolhe uma ID de sessão, passa o token GitHub do usuário na sessão e fornece uma lista de permissões de ferramenta explícita.\n\n![Diagrama: Fluxograma mostrando o processo descrito.](/assets/images/help/copilot/copilot-sdk/setup-multi-tenancy-diagram-0.png)\n\nUse estas regras:\n\n* Sempre inicie o cliente ou o runtime em `mode: \"empty\"`.\n* Use IDs de sessão exclusivas e armazene metadados de propriedade no banco de dados do aplicativo.\n* Verifique a titularidade antes de `resumeSession`, `deleteSession` ou qualquer ação da interface do usuário que faça referência a um ID de sessão.\n* Forneça `gitHubToken` em cada sessão quando as solicitações devem ser executadas em nome do usuário.\n* Registre apenas as ferramentas que a sessão necessita e prefira listas de permissões com origem especificada, como `custom:*` ou `mcp:search_docs`.\n* Defina `sessionIdleTimeoutSeconds` e exclua as sessões de fluxo de trabalho concluídas explicitamente.\n\n## Armadilhas comuns\n\n* Esquecendo `mode: \"empty\"`. O modo padrão `copilot-cli` expõe um comportamento no estilo de CLI e pode expor o sistema de arquivos do host por meio de ferramentas disponíveis no ambiente.\n* Não definir `sessionIdleTimeoutSeconds`. Servidores que permanecem em execução por longos períodos podem acumular sessões ociosas se não as encerrarem.\n* Compartilhando um `gitHubToken` entre usuários em vez de passar um token por sessão.\n* Confiando em IDs de sessão fornecidas pelo cliente sem verificar a propriedade em seu back-end.\n* Configurando `baseDirectory` em um cliente que se conecta a um ambiente de execução existente e esperando que ele mova o armazenamento do ambiente de execução. Em vez disso, configure o processo de runtime.\n* Permitir padrões de ferramentas amplos, como `builtin:*` sem examinar se cada ferramenta é apropriada para seus usuários.\n\n## Consulte também\n\n* [Escalabilidade e multitenância](/pt/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/setup/scaling): topologias de implantação, padrões de armazenamento e comparações de isolamento\n* [Configuração de serviços de back-end](/pt/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/setup/backend-services): executando o ambiente de execução no modo servidor sem interface gráfica\n* [BYOK (Bring Your Own Key - traga sua própria chave)](/pt/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/auth/byok): usando suas próprias credenciais de provedor de modelo\n* [Sessões de nuvem](/pt/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/features/cloud-sessions): roteamento de trabalho selecionado para sessões de nuvem\n* [Retomada e persistência da sessão](/pt/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/features/session-persistence): gerenciando o estado de sessão retomável\n* [Features](/pt/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/features): ferramentas, eventos, ganchos e recursos avançados do SDK"}