# Identidade gerenciada do Azure com BYOK

O BYOK (Bring Your Own Key - traga sua própria chave) do SDK GitHub Copilot dá suporte a chaves de API estáticas, mas as implantações Azure geralmente usam Identidade Gerenciada (Microsoft Entra ID) em vez de chaves de longa duração. O SDK do GitHub Copilot foi projetado para compor com o SDK de Identidade do Azure para obter flexibilidade máxima. Forneça um callback do provedor de token Bearer capaz de buscar tokens atualizados sob demanda usando uma API do SDK do Azure Identity.

<!-- markdownlint-disable GHD046 GHD005 -->

<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->

Este guia mostra como usar APIs do SDK de Identidade do Azure para autenticar com modelos do Microsoft Foundry por meio do SDK do GitHub Copilot. A maioria dos idiomas usa `DefaultAzureCredential`; O Rust usa `DeveloperToolsCredential` localmente e `ManagedIdentityCredential` em Azure.

## Como funciona

O ponto de extremidade do Microsoft Foundry compatível com OpenAI (`https://<resource-name>.openai.azure.com/openai/v1/`) aceita tokens bearer do Microsoft Entra ID em vez de chaves de API estáticas. Este guia usa uma função de callback do provedor de tokens para que o runtime do SDK do GitHub Copilot possa solicitar novos tokens sob demanda.

Usando Python como exemplo, o fluxo é:

1. Configure `DefaultAzureCredential` para seu ambiente.
2. Passe uma função de callback, em `bearer_token_provider` da configuração do provedor BYOK, que usa `DefaultAzureCredential` para obter um token para o escopo `https://ai.azure.com/.default`.
3. Permita que o SDK do GitHub Copilot solicite tokens novos sob demanda por meio desse callback.

![Diagrama: diagrama de sequência mostrando o processo descrito.](/assets/images/help/copilot/copilot-sdk/setup-azure-managed-identity-diagram-0.png)

## Exemplos de código

### Pré-requisitos

Instale os pacotes do SDK do Azure Identity e GitHub Copilot para seu idioma:

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

<!-- docs-validate: skip -->

```bash
dotnet add package GitHub.Copilot.SDK
dotnet add package Azure.Core
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

<!-- docs-validate: skip -->

```bash
go get github.com/github/copilot-sdk/go
go get github.com/Azure/azure-sdk-for-go/sdk/azidentity
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

<!-- docs-validate: skip -->

```xml
<dependency>
    <groupId>com.github</groupId>
    <artifactId>copilot-sdk-java</artifactId>
    <version>${copilot.sdk.version}</version>
</dependency>

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-identity</artifactId>
    <version>${azure.identity.version}</version>
</dependency>
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

<!-- docs-validate: skip -->

```bash
pip install github-copilot-sdk azure-identity
```

</div>

<div class="ghd-codetab" data-lang="rust" data-label="Rust"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Rust</div>

<!-- docs-validate: skip -->

```bash
cargo add github-copilot-sdk azure_identity azure_core
cargo add tokio --features macros,rt-multi-thread
```

</div>

<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

<!-- docs-validate: skip -->

```bash
npm install @github/copilot-sdk @azure/identity
```

</div>

</div>

### Use uma função de callback do provedor de token

Use esta abordagem quando você quiser que o runtime do SDK do GitHub Copilot solicite novos tokens sob demanda por meio de uma função de callback fornecida. O SDK de Identidade do Azure manipula o cache de token e o tempo de atualização.

Aqui estão implementações específicas do idioma:

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

<!-- docs-validate: skip -->

```csharp
using Azure.Core;
using Azure.Identity;
using GitHub.Copilot;

DefaultAzureCredential credential = new(
    DefaultAzureCredential.DefaultEnvironmentVariableName);
await using CopilotClient client = new();
string foundryUrl = Environment.GetEnvironmentVariable("FOUNDRY_RESOURCE_URL")!;

await using CopilotSession session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "gpt-5.5",
    Provider = new ProviderConfig
    {
        Type = "openai",
        BaseUrl = $"{foundryUrl}/openai/v1/",
        BearerTokenProvider = async _ =>
        {
            AccessToken token = await credential.GetTokenAsync(
                new TokenRequestContext(["https://ai.azure.com/.default"]));
            return token.Token;
        },
        WireApi = "responses",
    },
});

AssistantMessageEvent? response = await session.SendAndWaitAsync(
    new MessageOptions { Prompt = "Hello from Managed Identity!" });
Console.WriteLine(response?.Data.Content);
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

<!-- docs-validate: skip -->

```golang
package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "time"

    "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
    "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
    copilot "github.com/github/copilot-sdk/go"
)
func main() {
    opts := azidentity.DefaultAzureCredentialOptions{RequireAzureTokenCredentials: true}
    credential, err := azidentity.NewDefaultAzureCredential(&opts)
    if err != nil {
        log.Fatal(err)
    }

    getBearerToken := func(args copilot.ProviderTokenArgs) (string, error) {
        token, err := credential.GetToken(context.Background(), policy.TokenRequestOptions{
            Scopes: []string{"https://ai.azure.com/.default"},
        })
        if err != nil {
            return "", err
        }
        return token.Token, nil
    }

    client := copilot.NewClient(nil)
    if err := client.Start(context.Background()); err != nil {
        log.Fatal(err)
    }
    defer client.Stop()

    foundryURL := os.Getenv("FOUNDRY_RESOURCE_URL")

    session, err := client.CreateSession(context.Background(), &copilot.SessionConfig{
        Model: "gpt-5.5",
        Provider: &copilot.ProviderConfig{
            Type:                "openai",
            BaseURL:             fmt.Sprintf("%s/openai/v1/", foundryURL),
            BearerTokenProvider: getBearerToken,
            WireAPI:             "responses",
        },
    })
    if err != nil {
        log.Fatal(err)
    }
    defer session.Disconnect()

    ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
    defer cancel()

    response, err := session.SendAndWait(ctx, copilot.MessageOptions{
        Prompt: "Hello from Managed Identity!",
    })
    if err != nil {
        log.Fatal(err)
    }

    if response != nil {
        if data, ok := response.Data.(*copilot.AssistantMessageData); ok {
            fmt.Println(data.Content)
        }
    }
}
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

<!-- docs-validate: skip -->

```java
import com.azure.core.credential.TokenRequestContext;
import com.azure.identity.AzureIdentityEnvVars;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.github.copilot.CopilotClient;
import com.github.copilot.generated.AssistantMessageEvent;
import com.github.copilot.rpc.BearerTokenProvider;
import com.github.copilot.rpc.MessageOptions;
import com.github.copilot.rpc.ProviderConfig;
import com.github.copilot.rpc.SessionConfig;

public class ManagedIdentityExample {
    public static void main(String[] args) throws Exception {
        var credential = new DefaultAzureCredentialBuilder()
                .requireEnvVars(AzureIdentityEnvVars.AZURE_TOKEN_CREDENTIALS)
                .build();
        BearerTokenProvider tokenProvider = providerArgs ->
            credential
                .getToken(new TokenRequestContext().addScopes("https://ai.azure.com/.default"))
                .map(accessToken -> accessToken.getToken())
                .toFuture();
        String foundryUrl = System.getenv("FOUNDRY_RESOURCE_URL");

        try (var client = new CopilotClient()) {
            client.start().get();

            var session = client.createSession(new SessionConfig()
                    .setModel("gpt-5.5")
                    .setProvider(new ProviderConfig()
                            .setType("openai")
                            .setBaseUrl(foundryUrl + "/openai/v1/")
                            .setBearerTokenProvider(tokenProvider)
                            .setWireApi("responses")))
                .get();

            AssistantMessageEvent response = session
                    .sendAndWait(new MessageOptions().setPrompt("Hello from Managed Identity!"))
                    .get();
            System.out.println(response.getData().content());

            session.disconnect().get();
        }
    }
}
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

<!-- docs-validate: skip -->

```python
import asyncio
import os

from azure.identity.aio import DefaultAzureCredential
from copilot import CopilotClient
from copilot.session import PermissionHandler, ProviderConfig

async def main():
    credential = DefaultAzureCredential(require_envvar=True)
    async def get_bearer_token(_args) -> str:
        token = await credential.get_token("https://ai.azure.com/.default")
        return token.token

    foundry_url = os.environ["FOUNDRY_RESOURCE_URL"]

    client = CopilotClient()
    await client.start()

    session = await client.create_session(
        on_permission_request=PermissionHandler.approve_all,
        model="gpt-5.5",
        provider=ProviderConfig(
            type="openai",
            base_url=f"{foundry_url.rstrip('/')}/openai/v1/",
            bearer_token_provider=get_bearer_token,
            wire_api="responses",
        ),
    )

    response = await session.send_and_wait("Hello from Managed Identity!")
    print(response.data.content)

    await client.stop()
    await credential.close()

asyncio.run(main())
```

</div>

<div class="ghd-codetab" data-lang="rust" data-label="Rust"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Rust</div>

<!-- docs-validate: skip -->

```rust
use std::sync::Arc;

use azure_core::credentials::TokenCredential;
use azure_identity::{DeveloperToolsCredential, ManagedIdentityCredential};
use github_copilot_sdk::{BearerTokenError, Client, ClientOptions, MessageOptions, ProviderTokenArgs};
use github_copilot_sdk::types::{ProviderConfig, SessionConfig};

fn credential_for_environment() -> azure_core::Result<Arc<dyn TokenCredential>> {
    match std::env::var("AZURE_TOKEN_CREDENTIALS").as_deref() {
        Ok("ManagedIdentityCredential") => Ok(ManagedIdentityCredential::new(None)?),
        _ => Ok(DeveloperToolsCredential::new(None)?),
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let credential = credential_for_environment()?;
    let foundry_url = std::env::var("FOUNDRY_RESOURCE_URL")?;

    let get_bearer_token = {
        let credential = credential.clone();
        move |_args: ProviderTokenArgs| {
            let credential = credential.clone();
            async move {
                let token = credential
                    .get_token(&["https://ai.azure.com/.default"], None)
                    .await
                    .map_err(|err| BearerTokenError::message(err.to_string()))?;
                Ok(token.token.secret().to_string())
            }
        }
    };

    let mut provider = ProviderConfig::default();
    provider.provider_type = Some("openai".to_string());
    provider.base_url = format!("{}/openai/v1/", foundry_url.trim_end_matches('/'));
    provider.bearer_token_provider = Some(Arc::new(get_bearer_token));
    provider.wire_api = Some("responses".to_string());

    let mut config = SessionConfig::default();
    config.model = Some("gpt-5.5".to_string());
    config.provider = Some(provider);

    let client = Client::start(ClientOptions::default()).await?;
    let session = client.create_session(config).await?;

    session
        .send_and_wait(MessageOptions::new("Hello from Managed Identity!"))
        .await?;

    session.disconnect().await?;
    client.stop().await?;
    Ok(())
}
```

</div>

<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

<!-- docs-validate: skip -->

```typescript
import { DefaultAzureCredential } from "@azure/identity";
import { CopilotClient } from "@github/copilot-sdk";

const credential = new DefaultAzureCredential({
  requiredEnvVars: ["AZURE_TOKEN_CREDENTIALS"],
});
const getBearerToken = async () => {
  const tokenResponse = await credential.getToken("https://ai.azure.com/.default");
  return tokenResponse.token;
};

const client = new CopilotClient();

const session = await client.createSession({
  model: "gpt-5.5",
  provider: {
    type: "openai",
    baseUrl: `${process.env.FOUNDRY_RESOURCE_URL}/openai/v1/`,
    bearerTokenProvider: getBearerToken,
    wireApi: "responses",
  },
});

const response = await session.sendAndWait({ prompt: "Hello from Managed Identity!" });
console.log(response?.data.content);

await client.stop();
```

</div>

</div>

## Configuração do ambiente

| Variable                                                                                                                                                                                                                                          | Description                                                                                                                                                                                                      | Example                                  |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
| `AZURE_TOKEN_CREDENTIALS`                                                                                                                                                                                                                         | Ao executar em **Azure**, defina-o como `ManagedIdentityCredential`. Ao executar **localmente**, configure-o para usar `dev` ou um nome de credencial de ferramenta de desenvolvedor, como `AzureCliCredential`. | `ManagedIdentityCredential`              |
| `AZURE_CLIENT_ID`                                                                                                                                                                                                                                 |                                                                                                                                                                                                                  |                                          |
| *Opcional.* Ao executar em **Azure**, defina-a como a ID do cliente de uma Identidade Gerenciada atribuída pelo usuário ao usar `ManagedIdentityCredential`. Se não estiver definido, Azure usará a Identidade Gerenciada atribuída pelo sistema. | `11111111-2222-3333-4444-555555555555`                                                                                                                                                                           |                                          |
| `FOUNDRY_RESOURCE_URL`                                                                                                                                                                                                                            | A URL do recurso Microsoft Foundry                                                                                                                                                                               | `https://<my-resource>.openai.azure.com` |

Nenhuma variável de ambiente de chave de API é necessária– a autenticação é tratada por credenciais de identidade Azure. Em .NET, Go, Java, Python e TypeScript, `DefaultAzureCredential` oferece suporte automático a:

* **Identidade Gerenciada** (atribuída pelo sistema ou atribuída pelo usuário): para aplicativos hospedados Azure
* **CLI do Azure** (`az login`): para desenvolvimento local
* **Variáveis de ambiente** (`AZURE_CLIENT_ID`, `AZURE_TENANT_ID`, `AZURE_CLIENT_SECRET`): para entidades de serviço
* **Identidade da carga de trabalho**: para Kubernetes

Em .NET, Go, Java, Python e TypeScript, `ManagedIdentityCredential` lê `AZURE_CLIENT_ID` para selecionar uma Identidade Gerenciada atribuída pelo usuário. Rust é uma exceção neste guia.

No Rust, use `DeveloperToolsCredential` para desenvolvimento local e `ManagedIdentityCredential` ao executar em Azure. Para outros idiomas, consulte a documentação em `DefaultAzureCredential` sobre a cadeia completa de credenciais:

* [.NET](https://aka.ms/azsdk/net/identity/credential-chains#defaultazurecredential-overview)
* [Go](https://aka.ms/azsdk/go/identity/credential-chains#defaultazurecredential-overview)
* [Java](https://aka.ms/azsdk/java/identity/credential-chains#defaultazurecredential-overview)
* [Python](https://aka.ms/azsdk/python/identity/credential-chains#defaultazurecredential-overview)
* [TypeScript](https://aka.ms/azsdk/js/identity/credential-chains#defaultazurecredential-overview)

## Quando usar esse padrão

| Scenario                                                     | Recomendação                                                                                          |
| ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- |
| Aplicativo hospedado no Azure com Identidade Gerenciada      |                                                                                                       |
| ✅ Usar esse padrão                                           |                                                                                                       |
| Aplicativo com entidade de serviço Microsoft Entra existente |                                                                                                       |
| ✅ Usar esse padrão                                           |                                                                                                       |
| Desenvolvimento local com `az login`                         |                                                                                                       |
| ✅ Usar esse padrão                                           |                                                                                                       |
| Ambiente não Azure com chave de API estática                 | Usar [BYOK (Bring Your Own Key - traga sua própria chave)](/pt/copilot/how-tos/copilot-sdk/auth/byok) |
| GitHub Copilot assinatura disponível                         | Usar [Configuração do OAuth do GitHub](/pt/copilot/how-tos/copilot-sdk/setup/github-oauth)            |

## Consulte também

* [BYOK (Bring Your Own Key - traga sua própria chave)](/pt/copilot/how-tos/copilot-sdk/auth/byok): Configuração de chave de API estática
* [Configuração de serviços de back-end](/pt/copilot/how-tos/copilot-sdk/setup/backend-services): Implantação do lado do servidor