Observasjonsautentiseringsoppsett

Agent 365-eksportøren krever en tokenløser for autentisering ved eksport av telemetri. Denne veiledningen omhandler oppsett for agenter bygd med SDK for Microsoft 365-agenter, og dekker både Agent 365-aktiverte agenter og egendefinerte motoragenter på .NET, Python og Node.js.

For distroinstallasjon, generell konfigurasjon og scenarioer uten agent-SDK kan du se Microsoft OpenTelemetry Distro.

Oversikt

Det finnes fire autentiseringsscenarioer, avhengig av agenttypen din og hvordan den henter tokens. Innhenting av tokens kan bruke On-Behalf-Of flow (OBO) eller Service-to-Service (S2S). Velg scenarioet som passer oppsettet ditt:

Scenario Description
Agent 365-aktivert med OBO Distroens innebygde AgenticTokenCache håndterer tokenanskaffelse automatisk. Ingen egendefinert løser nødvendig. Dette er den anbefalte tilnærmingen for Agent 365-aktiverte agenter.
Agent 365-aktivert med S2S Agenten henter et token ved å bruke den agentiske identitetskjeden (getAgenticApplicationToken + Microsoft Authentication Libraries (MSAL)). Krever en tilpasset TokenResolver. Bruk denne tilnærmingen når OBO ikke er tilgjengelig eller du trenger bare app-tokener.
Tilpasset motor med OBO Agenten får et brukertoken via Azure Bot OAuth, med omfang for observerbarhets-API-en. Krever en egendefinert TokenResolver og en Azure Bot OAuth-tilkobling.
Tilpasset motor med S2S Agenten skaffer seg et bare app-token ved hjelp av klientlegitimasjon. Krever en tilpasset TokenResolver. Appregistreringen må være en standard (ikke-agentisk) app.

Agent 365-aktivert med OBO

Agent 365-aktiverte agenter mottar forespørsler med agentisk identitet (agenticAppId, agenticUserId) fra Agent 365-plattformen. Med OBO sørger distribusjonens innebygde AgenticTokenCache for automatisk innhenting av token: ingen tilpasset tokenløser er nødvendig.

Forutsetning

  • Entra-appregistrering : En tjenestekontohaver (appregistrering) med Klient-ID, klienthemmelighet og leietaker-ID
  • Delegerte API-tillatelser : Legg til Agent365.Observability.OtelWrite (delegert), gi administratorsamtykke. For detaljerte trinn kan du se Gi tillatelsen.

Installasjon

På hver tur kaller agenten RegisterObservability-funksjonen med turkonteksten. Den innebygde bufferen bruker brukerens delegerte token fra AgenticUserAuthorization-behandlingsprogrammet for å utføre en OBO-utveksling og henter et token med omfang mot Agent365.Observability.OtelWrite.

For fullstendige oppsettinstruksjoner inkludert pakker, konfigurasjon og kodeeksempler kan du se Agentisk tokenbuffer med Agent Framework-apper.

Agent 365-aktivert med S2S

Agent 365-agenter kan også bruke S2S (tjeneste-til-tjeneste) autentisering i stedet for OBO. Agenten skaffer seg et token ved å bruke sin egen tjenestekontohaveridentitet via en totrinns agentisk identitetskjede:

  1. getAgenticApplicationToken(tenantId, agentId) : banen klientlegitimasjon + føderert administrert identitet (FMI)
  2. MSAL acquireTokenForClient med apptoken som clientAssertion og omfang api://9b975845-388f-4429-889e-eab1ef63949c/.default

Notat

Føderert administrert identitet (FMI) er en arkitektur der en administrert identitet deltar i arbeidslastidentitetsføderering via fødererte identitetsopplysninger, og muliggjør tokenutveksling og autentisering uten hemmeligheter basert på tillitsforhold mellom identiteter.

Du må angi et tilpasset TokenResolver og angi UseS2SEndpoint = true.

Forutsetning

  • Entra-appregistrering : En tjenestekontohaver (appregistrering) med Klient-ID, klienthemmelighet og leietaker-ID

  • API-tillatelser for programmet : Legg til Agent365.Observability.OtelWrite (Program), gi administrativt samtykke

  • Agent365.Observability.OtelWrite-approllen: Agentens tjenestekontohaver må ha OtelWrite-rollen tildelt til Agent365-observerbarhetsressursen. Bruk Agent 365 CLI:

    a365 setup permissions bot --config-dir "<path-to-config-dir>"
    

    Notat

    Rolleutfylling kan ta noen minutter. Innledende 401- eller 403-feil fra eksportendepunktet forventes i denne perioden.

Trinn 1: Miljøkonfigurasjon

Følgende kodeeksempler viser hvordan du setter de nødvendige tilkoblings-, leietaker-, klientlegitimasjons- og miljøvariablene for observerbarhetseksportøren før du aktiverer den tilpassede S2S-tokenflyten.

Ingen AgenticUserAuthorization-behandlingsprogram er nødvendig. S2S bruker den manuelle agentiske identitetskjeden (get_agentic_application_token + MSAL acquire_token_for_client) for å få et token med omfang for observerbarhetsressursen.

CONNECTIONSMAP__0__SERVICEURL=*
CONNECTIONSMAP__0__CONNECTION=SERVICE_CONNECTION

CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTID=<your-client-id>
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTSECRET=<your-client-secret>
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__TENANTID=<your-tenant-id>

ENABLE_A365_OBSERVABILITY=true
ENABLE_A365_OBSERVABILITY_EXPORTER=true

Trinn 2: Konfigurer distroen med en egendefinert tokenløser

Følgende eksempler viser hvordan du aktiverer Agent 365-eksport og registrerer en egendefinert TokenResolver slik at eksportøren kan hente S2S-tokens for hver agent og leietaker.

from microsoft.opentelemetry import use_microsoft_opentelemetry

_token_cache: dict[str, str] = {}

def token_resolver(agent_id: str, tenant_id: str) -> str | None:
    return _token_cache.get(f"{agent_id}:{tenant_id}")

use_microsoft_opentelemetry(
    enable_a365=True,
    a365_token_resolver=token_resolver,
    a365_use_s2s_endpoint=True,
    a365_enable_observability_exporter=True,
)

Trinn 3: Hent og bufre S2S-tokenet

For hver innkommende melding henter du S2S-tokenet gjennom den agentiske identitetskjeden og bufrer det for løseren.

import asyncio
from msal import ConfidentialClientApplication
from microsoft.opentelemetry.a365.core import BaggageBuilder, InvokeAgentScope, InvokeAgentScopeDetails, Request

OBSERVABILITY_S2S_SCOPE = "api://9b975845-388f-4429-889e-eab1ef63949c/.default"

async def get_agentic_s2s_token(connection, tenant_id: str, agent_id: str) -> str:
    # Step 1: Get agentic application token (client_credentials + fmi_path)
    app_token = await connection.get_agentic_application_token(tenant_id, agent_id)
    if not app_token:
        raise ValueError(f"Failed to get agentic app token for agent {agent_id}")

    # Step 2: Exchange for observability-scoped token
    cca = ConfidentialClientApplication(
        client_id=agent_id,
        authority=f"https://login.microsoftonline.com/{tenant_id}",
        client_credential={"client_assertion": app_token},
    )
    result = await asyncio.to_thread(
        lambda: cca.acquire_token_for_client(scopes=[OBSERVABILITY_S2S_SCOPE])
    )
    if not result or "access_token" not in result:
        raise ValueError(f"Token acquisition failed: {result}")
    return result["access_token"]

# In your message handler : use SDK helpers to get agent/tenant from the activity:
@AGENT_APP.activity("message")
async def on_message(context: TurnContext, _state: TurnState):
    # get_agentic_instance_id reads from recipient (SDK convention)
    agent_id = context.activity.get_agentic_instance_id()
    tenant_id = context.activity.get_agentic_tenant_id()

    # Acquire S2S token and cache BEFORE creating spans
    connection = CONNECTION_MANAGER.get_connection("SERVICE_CONNECTION")
    token = await get_agentic_s2s_token(connection, tenant_id, agent_id)
    _token_cache[f"{agent_id}:{tenant_id}"] = token

    # Wrap spans in BaggageBuilder so the exporter can resolve the token
    request = Request(content=user_message, session_id=None)
    with BaggageBuilder().tenant_id(tenant_id).agent_id(agent_id).build():
        invoke_scope = InvokeAgentScope.start(request, InvokeAgentScopeDetails(), agent_details)
        with invoke_scope:
            invoke_scope.record_input_messages([user_message])
            invoke_scope.record_output_messages([response])

Viktig!

Den manuelle totrinnsflyten (get_agentic_application_token + MSAL acquire_token_for_client) er nødvendig for S2S. AgenticUserAuthorization.get_token() returnerer et token som gjelder for 5a807f24-.../.default (Bot Framework), ikke for observerbarhetsressursen api://9b975845-.../.default : S2S-endepunktet avviser det med 401 InvalidAudience.

  • Bruk context.activity.get_agentic_instance_id() og get_agentic_tenant_id() for å lese agenten og leietakeren fra aktiviteten (leser fra recipient i henhold til SDK-konvensjonen).
  • Skaff og bufre S2S-tokenet før du oppretter strekk. Eksportørens BatchSpanProcessor kan tømmes før behandlingsprogrammet er ferdig: hvis tokenet ikke er bufret ennå, feiler eksporten.
  • Pakk inn alle A365-omfang i BaggageBuilder slik at eksportøren vet hvilken agent og leietaker den skal løse tokens for. Uten bagasje forkastes strekk stille med «Ingen strekk med leier/agentidentitet funnet.»

Tilpasset motor med OBO

Egendefinerte motoragenter bruker standard appregistreringer med Azure Bot OAuth-tilkoblinger, ikke agentisk identitetskjede. Ved bruk av OBO får agenten en brukertoken gjennom Azure Bot OAuth som allerede har tilgang til A365-observerbarhets-API-et via Bot Framework-tokentjeneste. Et enkelt getToken- eller GetTurnTokenAsync-kall returnerer riktig token med korrekt omfang, så du trenger ikke exchangeToken.

Forutsetning

Entra-appregistrering med delegerte API-tillatelser. Legg til Agent365.Observability.OtelWrite (delegert) og gi administratorsamtykke

Viktig!

agentId i tokenbufferen må matche appregistreringens klient-ID – ikke aktivitetens agenticAppId, som ikke finnes for egendefinerte motoragenter. Eksportnettadressen inkluderer agentId, og en konflikt forårsaker HTTP 403.

Trinn 1: Miljø- og appkonfigurasjon

Følgende eksempler viser hvordan du konfigurerer appen og kjøretidsmiljøet, inkludert tjenestetilkoblingsverdier, leietaker- og klientinnstillinger, samt nødvendige autorisasjonstildelinger.

# .env
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTID=<your-client-id>
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTSECRET=<your-client-secret>
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__TENANTID=<your-tenant-id>

CONNECTIONSMAP__0__CONNECTION=SERVICE_CONNECTION
CONNECTIONSMAP__0__SERVICEURL=*

# Auth handler config : TYPE is required, name is uppercased by load_configuration_from_env
AGENTAPPLICATION__USERAUTHORIZATION__HANDLERS__OBOCONNECTIONPROFILE__TYPE=UserAuthorization
AGENTAPPLICATION__USERAUTHORIZATION__HANDLERS__OBOCONNECTIONPROFILE__SETTINGS__AZUREBOTOAUTHCONNECTIONNAME=oboConnectionProfile
AGENTAPPLICATION__USERAUTHORIZATION__HANDLERS__OBOCONNECTIONPROFILE__SETTINGS__SCOPES=api://9b975845-388f-4429-889e-eab1ef63949c/Agent365.Observability.OtelWrite

ENABLE_A365_OBSERVABILITY=true
ENABLE_A365_OBSERVABILITY_EXPORTER=true

Viktig!

load_configuration_from_env konverterer alle miljøvariabelnøkler til store bokstaver. Behandlingsprogramnavnet blir OBOCONNECTIONPROFILE, og du må referere til det med nøyaktig samme skrivemåte i auth_handlers- og get_token()-kall. Manglende TYPE forårsaker Auth handler ... not recognized or not configured under kjøring.

Trinn 2: Konfigurer distroen for OBO

Følgende eksempler viser hvordan du aktiverer Agent 365-eksport, holder eksportøren på OBO-endepunktet og registrerer en tilpasset TokenResolver som returnerer delegerte tokens under eksportprosessen.

from microsoft.opentelemetry import use_microsoft_opentelemetry

_token_cache: dict[str, str] = {}

def token_resolver(agent_id: str, tenant_id: str) -> str | None:
    return _token_cache.get(f"{agent_id}:{tenant_id}")

environ["ENABLE_A365_OBSERVABILITY_EXPORTER"] = "true"

use_microsoft_opentelemetry(
    enable_a365=True,
    a365_token_resolver=token_resolver,
    a365_use_s2s_endpoint=False,  # OBO uses /observability endpoint
    a365_enable_observability_exporter=True,
)

Notat

OBO-modus krever jwt_authorization_middlewareaiohttpApplication (validerer den mottatte JWT (JSON Web Token) fra Bot Framework). S2S/emulatorbanen skal ikke inkludere denne mellomvaren.

from microsoft_agents.hosting.aiohttp import jwt_authorization_middleware
app = Application(middlewares=[jwt_authorization_middleware])

Trinn 3: Hent OBO-tokenet

Følgende eksempler viser hvordan du kan be om et delegert OBO-token fra den konfigurerte Azure Bot OAuth-tilkoblingen, og deretter lagre det i buffer per appklient og leietaker for eksportørkomponenten.

from microsoft_agents.hosting.core import (
    AgentApplication, Authorization, MemoryStorage, TurnContext, TurnState,
)
from microsoft_agents.activity import load_configuration_from_env
from microsoft_agents.authentication.msal import MsalConnectionManager
from microsoft_agents.hosting.aiohttp import CloudAdapter

# Auth handlers are loaded from .env via load_configuration_from_env (see Environment config above)
agents_sdk_config = load_configuration_from_env(environ)

STORAGE = MemoryStorage()
CONNECTION_MANAGER = MsalConnectionManager(**agents_sdk_config)
ADAPTER = CloudAdapter(connection_manager=CONNECTION_MANAGER)
AUTHORIZATION = Authorization(STORAGE, CONNECTION_MANAGER, **agents_sdk_config)

AGENT_APP = AgentApplication[TurnState](
    storage=STORAGE, adapter=ADAPTER, authorization=AUTHORIZATION, **agents_sdk_config,
)

CLIENT_ID = environ.get("CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTID", "")
TENANT_ID = environ.get("CONNECTIONS__SERVICE_CONNECTION__SETTINGS__TENANTID", "")

# Message handler : get_token returns a token already scoped to the observability API.
# The Azure Bot Token Service performs the OBO exchange internally based on the
# OAuth connection's configured scope. No manual MSAL exchange_token call is needed.
@AGENT_APP.activity("message", auth_handlers=["OBOCONNECTIONPROFILE"])
async def on_message(context: TurnContext, _state: TurnState):
    token_response = await AGENT_APP.auth.get_token(context, "OBOCONNECTIONPROFILE")
    # token_response.token has aud=<a365-observability-app-id>,
    # scp=Agent365.Observability.OtelWrite
    _token_cache[f"{CLIENT_ID}:{TENANT_ID}"] = token_response.token

Viktig!

Azure Portal-forutsetning: Azure Bot OAuth-tilkoblingen med navnet oboConnectionProfile må ha sine omfangene satt til api://9b975845-388f-4429-889e-eab1ef63949c/Agent365.Observability.OtelWrite. Uten denne innstillingen blir tokenet begrenset til robotens egen målgruppe (api://botid-...), og eksporten feiler med HTTP 401 (InvalidAudience).

Notat

AGENT_APP.auth.get_token() returnerer tokenet med korrekt omfang direkte – ingen exchange_token()-kall er nødvendig. Bot Framework-tokentjenesten håndterer OBO-utvekslingen når OAuth-tilkoblingsomfanget retter seg mot A365-observerbarhetsressursen.

Tilpasset motor med S2S

Egendefinerte motoragenter kan bruke S2S (klientlegitimasjon) for å hente et bare app-token ved å bruke tjenestetilkoblingslegitimasjonen. Denne metoden bruker standard MSAL-klientlegitimasjon – ingen agentisk identitetskjede kreves.

Forutsetning

  • Azure AD-appregistrering : Må være en app med egendefinert motor (standard). Agent 365-aktiverte appregistreringer kan ikke bruke vanlig client_credentials for ressursen for observerbarhet (AADSTS82001).
  • Programtillatelser: Legg til Agent365.Observability.OtelWrite (Program, ikke delegert), og gi administratorens samtykke.

Viktig!

agentId som brukes til bufring være ServiceConnections ClientId. Eksportnettadressen er /observabilityService/tenants/{tenantId}/otlp/agents/{agentId}/traces : et avvik fører til HTTP 403.

Trinn 1: Miljø- og appkonfigurasjon

Følgende eksempler viser hvordan du konfigurerer appen og kjøretidsmiljøet, inkludert tjenestetilkoblingsverdier, leietaker- og klientinnstillinger, samt nødvendige autorisasjonstildelinger.

# .env
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTID=<your-client-id>
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTSECRET=<your-client-secret>
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__TENANTID=<your-tenant-id>

CONNECTIONSMAP__0__CONNECTION=SERVICE_CONNECTION
CONNECTIONSMAP__0__SERVICEURL=*

ENABLE_A365_OBSERVABILITY=true
ENABLE_A365_OBSERVABILITY_EXPORTER=true

Trinn 2: Konfigurer distroen for S2S

Følgende eksempler viser hvordan du aktiverer Agent 365-eksport, setter eksportøren til S2S-endepunktet, og registrerer en egendefinert TokenResolver for tokenoppslag under eksport.

from microsoft.opentelemetry import use_microsoft_opentelemetry

_token_cache: dict[str, str] = {}

def token_resolver(agent_id: str, tenant_id: str) -> str | None:
    return _token_cache.get(f"{agent_id}:{tenant_id}")

use_microsoft_opentelemetry(
    enable_a365=True,
    a365_token_resolver=token_resolver,
    a365_use_s2s_endpoint=True,  # S2S uses /observabilityService endpoint
    a365_enable_observability_exporter=True,
)

Trinn 3: Hent S2S-tokenet

Følgende eksempler viser hvordan du kan be om et bare app-tilgangstoken for observerbarhetsressursen ved å bruke tjenestetilkoblingsinformasjonen, og deretter lagre det per agent og leietaker for eksportøren.

# Force agentId to ServiceConnection ClientId (custom engine agents have no agenticAppId)
agent_id = os.environ.get("CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTID")
tenant_id = os.environ.get("CONNECTIONS__SERVICE_CONNECTION__SETTINGS__TENANTID")

connection = CONNECTION_MANAGER.get_connection("SERVICE_CONNECTION")
token = await connection.get_access_token(
    resource_url="https://login.microsoftonline.com",
    scopes=["api://9b975845-388f-4429-889e-eab1ef63949c/.default"],
)
_token_cache[f"{agent_id}:{tenant_id}"] = token

Trinn 4: Sett bagasje for strekkeksport

Agent365-eksportøren krever at bagasje (leietaker-ID og agent-ID) settes på strekkonteksten. Uten at dette er satt dropper eksportøren strekk i bakgrunnen med meldingen No spans with tenant/agent identity found..

from microsoft.opentelemetry.a365.core import BaggageBuilder, InvokeAgentScope

# Baggage must wrap the span as a context manager
with BaggageBuilder().tenant_id(tenant_id).agent_id(agent_id).build():
    invoke_scope = InvokeAgentScope.start(request, InvokeAgentScopeDetails(), agent_details)
    with invoke_scope:
        invoke_scope.record_input_messages([user_message])
        invoke_scope.record_output_messages([response])