{"meta":{"title":"Identidad administrada de Azure con BYOK","intro":"El BYOK (traiga su propia clave) del SDK de GitHub Copilot admite claves de API estáticas, pero las implementaciones de Azure suelen usar identidad administrada (Microsoft Entra ID) en lugar de claves de larga duración. El SDK de GitHub Copilot está diseñado para integrarse con el SDK Azure Identity y ofrecer la máxima flexibilidad. Proporcione una devolución de llamada del proveedor de tokens de portador que pueda capturar tokens nuevos a petición mediante una API del SDK de identidad de Azure.","product":"GitHub Copilot","breadcrumbs":[{"href":"/es/copilot","title":"GitHub Copilot"},{"href":"/es/copilot/how-tos","title":"Procedimientos"},{"href":"/es/copilot/how-tos/copilot-sdk","title":"SDK de Copilot"},{"href":"/es/copilot/how-tos/copilot-sdk/setup","title":"Configuración del SDK de Copilot"},{"href":"/es/copilot/how-tos/copilot-sdk/setup/azure-managed-identity","title":"Identidad Administrada de Azure"}],"documentType":"article"},"body":"# Identidad administrada de Azure con BYOK\n\nEl BYOK (traiga su propia clave) del SDK de GitHub Copilot admite claves de API estáticas, pero las implementaciones de Azure suelen usar identidad administrada (Microsoft Entra ID) en lugar de claves de larga duración. El SDK de GitHub Copilot está diseñado para integrarse con el SDK Azure Identity y ofrecer la máxima flexibilidad. Proporcione una devolución de llamada del proveedor de tokens de portador que pueda capturar tokens nuevos a petición mediante una API del SDK de identidad de Azure.\n\n<!-- markdownlint-disable GHD046 GHD005 -->\n\n<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->\n\nEn esta guía se muestra cómo usar las API del SDK de Azure Identity para autenticarse con modelos de Microsoft Foundry a través del SDK de GitHub Copilot. La mayoría de los idiomas usan `DefaultAzureCredential`; Rust usa `DeveloperToolsCredential` localmente y `ManagedIdentityCredential` en Azure.\n\n## Cómo funciona\n\nEl punto de conexión compatible con OpenAI de Microsoft Foundry (`https://<resource-name>.openai.azure.com/openai/v1/`) acepta tokens de portador de Microsoft Entra ID en lugar de usar claves de API estáticas. Esta guía usa una función callback del proveedor de tokens para que el runtime del SDK de GitHub Copilot pueda solicitar tokens actualizados cuando sea necesario.\n\nCon Python como ejemplo, el flujo es:\n\n1. Configura `DefaultAzureCredential` para tu entorno.\n2. Pase una devolución de llamada, en `bearer_token_provider` de la configuración del proveedor BYOK, que usa `DefaultAzureCredential` para obtener un token para el `https://ai.azure.com/.default` ámbito.\n3. Deje que el SDK de GitHub Copilot solicite nuevos tokens cuando sea necesario mediante esa función de callback.\n\n![Diagrama: diagrama de secuencia que muestra el proceso descrito.](/assets/images/help/copilot/copilot-sdk/setup-azure-managed-identity-diagram-0.png)\n\n## Ejemplos de código\n\n### Prerequisites\n\nInstale los paquetes Azure Identity y GitHub Copilot SDK para el idioma:\n\n<div class=\"ghd-codetabs\">\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<!-- docs-validate: skip -->\n\n```bash\ndotnet add package GitHub.Copilot.SDK\ndotnet add package Azure.Core\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<!-- docs-validate: skip -->\n\n```bash\ngo get github.com/github/copilot-sdk/go\ngo get github.com/Azure/azure-sdk-for-go/sdk/azidentity\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<!-- docs-validate: skip -->\n\n```xml\n<dependency>\n    <groupId>com.github</groupId>\n    <artifactId>copilot-sdk-java</artifactId>\n    <version>${copilot.sdk.version}</version>\n</dependency>\n\n<dependency>\n    <groupId>com.azure</groupId>\n    <artifactId>azure-identity</artifactId>\n    <version>${azure.identity.version}</version>\n</dependency>\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<!-- docs-validate: skip -->\n\n```bash\npip install github-copilot-sdk azure-identity\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<!-- docs-validate: skip -->\n\n```bash\ncargo add github-copilot-sdk azure_identity azure_core\ncargo add tokio --features macros,rt-multi-thread\n```\n\n</div>\n\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<!-- docs-validate: skip -->\n\n```bash\nnpm install @github/copilot-sdk @azure/identity\n```\n\n</div>\n\n</div>\n\n### Uso de una devolución de llamada del proveedor de tokens\n\nUse este enfoque cuando desee que el entorno de ejecución del SDK de GitHub Copilot solicite tokens nuevos a petición a través de una devolución de llamada que proporcione. El SDK de Azure Identity controla el almacenamiento en caché de tokens y el tiempo de actualización.\n\nEstas son implementaciones específicas del lenguaje:\n\n<div class=\"ghd-codetabs\">\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<!-- docs-validate: skip -->\n\n```csharp\nusing Azure.Core;\nusing Azure.Identity;\nusing GitHub.Copilot;\n\nDefaultAzureCredential credential = new(\n    DefaultAzureCredential.DefaultEnvironmentVariableName);\nawait using CopilotClient client = new();\nstring foundryUrl = Environment.GetEnvironmentVariable(\"FOUNDRY_RESOURCE_URL\")!;\n\nawait using CopilotSession session = await client.CreateSessionAsync(new SessionConfig\n{\n    Model = \"gpt-5.5\",\n    Provider = new ProviderConfig\n    {\n        Type = \"openai\",\n        BaseUrl = $\"{foundryUrl}/openai/v1/\",\n        BearerTokenProvider = async _ =>\n        {\n            AccessToken token = await credential.GetTokenAsync(\n                new TokenRequestContext([\"https://ai.azure.com/.default\"]));\n            return token.Token;\n        },\n        WireApi = \"responses\",\n    },\n});\n\nAssistantMessageEvent? response = await session.SendAndWaitAsync(\n    new MessageOptions { Prompt = \"Hello from Managed Identity!\" });\nConsole.WriteLine(response?.Data.Content);\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<!-- docs-validate: skip -->\n\n```golang\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n    \"os\"\n    \"time\"\n\n    \"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy\"\n    \"github.com/Azure/azure-sdk-for-go/sdk/azidentity\"\n    copilot \"github.com/github/copilot-sdk/go\"\n)\nfunc main() {\n    opts := azidentity.DefaultAzureCredentialOptions{RequireAzureTokenCredentials: true}\n    credential, err := azidentity.NewDefaultAzureCredential(&opts)\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    getBearerToken := func(args copilot.ProviderTokenArgs) (string, error) {\n        token, err := credential.GetToken(context.Background(), policy.TokenRequestOptions{\n            Scopes: []string{\"https://ai.azure.com/.default\"},\n        })\n        if err != nil {\n            return \"\", err\n        }\n        return token.Token, nil\n    }\n\n    client := copilot.NewClient(nil)\n    if err := client.Start(context.Background()); err != nil {\n        log.Fatal(err)\n    }\n    defer client.Stop()\n\n    foundryURL := os.Getenv(\"FOUNDRY_RESOURCE_URL\")\n\n    session, err := client.CreateSession(context.Background(), &copilot.SessionConfig{\n        Model: \"gpt-5.5\",\n        Provider: &copilot.ProviderConfig{\n            Type:                \"openai\",\n            BaseURL:             fmt.Sprintf(\"%s/openai/v1/\", foundryURL),\n            BearerTokenProvider: getBearerToken,\n            WireAPI:             \"responses\",\n        },\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n    defer session.Disconnect()\n\n    ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)\n    defer cancel()\n\n    response, err := session.SendAndWait(ctx, copilot.MessageOptions{\n        Prompt: \"Hello from Managed Identity!\",\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    if response != nil {\n        if data, ok := response.Data.(*copilot.AssistantMessageData); ok {\n            fmt.Println(data.Content)\n        }\n    }\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<!-- docs-validate: skip -->\n\n```java\nimport com.azure.core.credential.TokenRequestContext;\nimport com.azure.identity.AzureIdentityEnvVars;\nimport com.azure.identity.DefaultAzureCredentialBuilder;\nimport com.github.copilot.CopilotClient;\nimport com.github.copilot.generated.AssistantMessageEvent;\nimport com.github.copilot.rpc.BearerTokenProvider;\nimport com.github.copilot.rpc.MessageOptions;\nimport com.github.copilot.rpc.ProviderConfig;\nimport com.github.copilot.rpc.SessionConfig;\n\npublic class ManagedIdentityExample {\n    public static void main(String[] args) throws Exception {\n        var credential = new DefaultAzureCredentialBuilder()\n                .requireEnvVars(AzureIdentityEnvVars.AZURE_TOKEN_CREDENTIALS)\n                .build();\n        BearerTokenProvider tokenProvider = providerArgs ->\n            credential\n                .getToken(new TokenRequestContext().addScopes(\"https://ai.azure.com/.default\"))\n                .map(accessToken -> accessToken.getToken())\n                .toFuture();\n        String foundryUrl = System.getenv(\"FOUNDRY_RESOURCE_URL\");\n\n        try (var client = new CopilotClient()) {\n            client.start().get();\n\n            var session = client.createSession(new SessionConfig()\n                    .setModel(\"gpt-5.5\")\n                    .setProvider(new ProviderConfig()\n                            .setType(\"openai\")\n                            .setBaseUrl(foundryUrl + \"/openai/v1/\")\n                            .setBearerTokenProvider(tokenProvider)\n                            .setWireApi(\"responses\")))\n                .get();\n\n            AssistantMessageEvent response = session\n                    .sendAndWait(new MessageOptions().setPrompt(\"Hello from Managed Identity!\"))\n                    .get();\n            System.out.println(response.getData().content());\n\n            session.disconnect().get();\n        }\n    }\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<!-- docs-validate: skip -->\n\n```python\nimport asyncio\nimport os\n\nfrom azure.identity.aio import DefaultAzureCredential\nfrom copilot import CopilotClient\nfrom copilot.session import PermissionHandler, ProviderConfig\n\nasync def main():\n    credential = DefaultAzureCredential(require_envvar=True)\n    async def get_bearer_token(_args) -> str:\n        token = await credential.get_token(\"https://ai.azure.com/.default\")\n        return token.token\n\n    foundry_url = os.environ[\"FOUNDRY_RESOURCE_URL\"]\n\n    client = CopilotClient()\n    await client.start()\n\n    session = await client.create_session(\n        on_permission_request=PermissionHandler.approve_all,\n        model=\"gpt-5.5\",\n        provider=ProviderConfig(\n            type=\"openai\",\n            base_url=f\"{foundry_url.rstrip('/')}/openai/v1/\",\n            bearer_token_provider=get_bearer_token,\n            wire_api=\"responses\",\n        ),\n    )\n\n    response = await session.send_and_wait(\"Hello from Managed Identity!\")\n    print(response.data.content)\n\n    await client.stop()\n    await credential.close()\n\nasyncio.run(main())\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<!-- docs-validate: skip -->\n\n```rust\nuse std::sync::Arc;\n\nuse azure_core::credentials::TokenCredential;\nuse azure_identity::{DeveloperToolsCredential, ManagedIdentityCredential};\nuse github_copilot_sdk::{BearerTokenError, Client, ClientOptions, MessageOptions, ProviderTokenArgs};\nuse github_copilot_sdk::types::{ProviderConfig, SessionConfig};\n\nfn credential_for_environment() -> azure_core::Result<Arc<dyn TokenCredential>> {\n    match std::env::var(\"AZURE_TOKEN_CREDENTIALS\").as_deref() {\n        Ok(\"ManagedIdentityCredential\") => Ok(ManagedIdentityCredential::new(None)?),\n        _ => Ok(DeveloperToolsCredential::new(None)?),\n    }\n}\n\n#[tokio::main]\nasync fn main() -> Result<(), Box<dyn std::error::Error>> {\n    let credential = credential_for_environment()?;\n    let foundry_url = std::env::var(\"FOUNDRY_RESOURCE_URL\")?;\n\n    let get_bearer_token = {\n        let credential = credential.clone();\n        move |_args: ProviderTokenArgs| {\n            let credential = credential.clone();\n            async move {\n                let token = credential\n                    .get_token(&[\"https://ai.azure.com/.default\"], None)\n                    .await\n                    .map_err(|err| BearerTokenError::message(err.to_string()))?;\n                Ok(token.token.secret().to_string())\n            }\n        }\n    };\n\n    let mut provider = ProviderConfig::default();\n    provider.provider_type = Some(\"openai\".to_string());\n    provider.base_url = format!(\"{}/openai/v1/\", foundry_url.trim_end_matches('/'));\n    provider.bearer_token_provider = Some(Arc::new(get_bearer_token));\n    provider.wire_api = Some(\"responses\".to_string());\n\n    let mut config = SessionConfig::default();\n    config.model = Some(\"gpt-5.5\".to_string());\n    config.provider = Some(provider);\n\n    let client = Client::start(ClientOptions::default()).await?;\n    let session = client.create_session(config).await?;\n\n    session\n        .send_and_wait(MessageOptions::new(\"Hello from Managed Identity!\"))\n        .await?;\n\n    session.disconnect().await?;\n    client.stop().await?;\n    Ok(())\n}\n```\n\n</div>\n\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<!-- docs-validate: skip -->\n\n```typescript\nimport { DefaultAzureCredential } from \"@azure/identity\";\nimport { CopilotClient } from \"@github/copilot-sdk\";\n\nconst credential = new DefaultAzureCredential({\n  requiredEnvVars: [\"AZURE_TOKEN_CREDENTIALS\"],\n});\nconst getBearerToken = async () => {\n  const tokenResponse = await credential.getToken(\"https://ai.azure.com/.default\");\n  return tokenResponse.token;\n};\n\nconst client = new CopilotClient();\n\nconst session = await client.createSession({\n  model: \"gpt-5.5\",\n  provider: {\n    type: \"openai\",\n    baseUrl: `${process.env.FOUNDRY_RESOURCE_URL}/openai/v1/`,\n    bearerTokenProvider: getBearerToken,\n    wireApi: \"responses\",\n  },\n});\n\nconst response = await session.sendAndWait({ prompt: \"Hello from Managed Identity!\" });\nconsole.log(response?.data.content);\n\nawait client.stop();\n```\n\n</div>\n\n</div>\n\n## Configuración de entorno\n\n| Variable                                                                                                                                                                                                                                                            | Description                                                                                                                                                                                                                  | Example                                  |\n| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |\n| `AZURE_TOKEN_CREDENTIALS`                                                                                                                                                                                                                                           | Cuando se ejecute en **Azure**, configúrelo como `ManagedIdentityCredential`. Al ejecutar **localmente**, configúrelo como `dev` o como un nombre de credencial de una herramienta de desarrollo, como `AzureCliCredential`. | `ManagedIdentityCredential`              |\n| `AZURE_CLIENT_ID`                                                                                                                                                                                                                                                   |                                                                                                                                                                                                                              |                                          |\n| *Opcional.* Cuando se ejecuta en **Azure**, establézcalo en el identificador de cliente de una identidad administrada asignada por el usuario al usar `ManagedIdentityCredential`. Si no se establece, Azure usa la identidad administrada asignada por el sistema. | `11111111-2222-3333-4444-555555555555`                                                                                                                                                                                       |                                          |\n| `FOUNDRY_RESOURCE_URL`                                                                                                                                                                                                                                              | Dirección URL del recurso Microsoft Foundry                                                                                                                                                                                  | `https://<my-resource>.openai.azure.com` |\n\nNo se necesita ninguna variable de entorno de clave de API: la autenticación se controla mediante Azure credenciales de identidad. En .NET, Go, Java, Python y TypeScript, `DefaultAzureCredential` admite automáticamente:\n\n* **Identidad administrada** (asignada por el sistema o asignada por el usuario): para aplicaciones hospedadas Azure\n* **CLI de Azure** (`az login`): para el desarrollo local\n* **Variables de entorno** (`AZURE_CLIENT_ID`, `AZURE_TENANT_ID`, `AZURE_CLIENT_SECRET`): para entidades de servicio\n* **Identidad de carga de trabajo**: para Kubernetes\n\nEn .NET, Go, Java, Python y TypeScript, `ManagedIdentityCredential` lee `AZURE_CLIENT_ID` para seleccionar una identidad administrada asignada por el usuario. Rust es una excepción en esta guía.\n\nEn Rust, use `DeveloperToolsCredential` para el desarrollo local y `ManagedIdentityCredential` cuando se ejecute en Azure. Para otros idiomas, consulte la documentación de la cadena completa de credenciales en `DefaultAzureCredential`:\n\n* [.NET](https://aka.ms/azsdk/net/identity/credential-chains#defaultazurecredential-overview)\n* [Go](https://aka.ms/azsdk/go/identity/credential-chains#defaultazurecredential-overview)\n* [Java](https://aka.ms/azsdk/java/identity/credential-chains#defaultazurecredential-overview)\n* [Python](https://aka.ms/azsdk/python/identity/credential-chains#defaultazurecredential-overview)\n* [TypeScript](https://aka.ms/azsdk/js/identity/credential-chains#defaultazurecredential-overview)\n\n## Cuándo usar este patrón\n\n| Escenario                                                           | Recomendación                                                                               |\n| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |\n| Aplicación hospedada en Azure con identidad administrada            |                                                                                             |\n| ✅ Usa este patrón                                                   |                                                                                             |\n| Aplicación con una entidad de servicio existente de Microsoft Entra |                                                                                             |\n| ✅ Usa este patrón                                                   |                                                                                             |\n| Desarrollo local con `az login`                                     |                                                                                             |\n| ✅ Usa este patrón                                                   |                                                                                             |\n| Entorno que no es de Azure con clave de API estática                | Usar [BYOK (traiga su propia clave)](/es/copilot/how-tos/copilot-sdk/auth/byok)             |\n| GitHub Copilot suscripción disponible                               | Usar [Configuración de OAuth de GitHub](/es/copilot/how-tos/copilot-sdk/setup/github-oauth) |\n\n## Consulte también\n\n* [BYOK (traiga su propia clave)](/es/copilot/how-tos/copilot-sdk/auth/byok): configuración de clave de API estática\n* [Configuración de servicios back-end](/es/copilot/how-tos/copilot-sdk/setup/backend-services): implementación del lado servidor"}