Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Eksportir Agent 365 memerlukan token resolver untuk diautentikasi saat mengekspor telemetri. Panduan ini mencakup pengaturan untuk agen yang dibuat menggunakan Agen SDK Microsoft 365, baik untuk agen yang diaktifkan dengan Agent 365 maupun agen dengan agen mesin kustom di .NET, Python, dan Node.js.
Untuk instalasi distro, konfigurasi umum, dan skenario non-Agent SDK, lihat Microsoft OpenTelemetry Distro.
Ikhtisar
Ada empat skenario autentikasi, tergantung pada jenis agen Anda dan cara memperoleh token. Akuisisi token dapat diperoleh menggunakan alur On-Behalf-Of (OBO) atau Service-to-Service (S2S). Pilih skenario yang paling sesuai dengan konfigurasi Anda:
| Skenario | Deskripsi |
|---|---|
| Agent 365 yang diaktifkan menggunakan OBO | Komponen bawaan distro AgenticTokenCache menangani akuisisi token secara otomatis. Tidak diperlukan resolver khusus. Ini adalah pendekatan yang direkomendasikan untuk agen yang mendukung Agent 365. |
| Agent 365 yang diaktifkan menggunakan S2S | Agen ini memperoleh token menggunakan rantai identitas agenik (getAgenticApplicationToken + Microsoft Authentication Libraries (MSAL)). Memerlukan TokenResolver kustom. Gunakan pendekatan ini saat OBO tidak tersedia atau Anda memerlukan token khusus aplikasi. |
| Mesin kustom menggunakan OBO | Agen mendapatkan token pengguna melalui Azure Bot OAuth, dengan cakupan ke API observabilitas. Memerlukan TokenResolver kustom dan koneksi Azure Bot OAuth. |
| Mesin kustom menggunakan S2S | Agen memperoleh token khusus aplikasi menggunakan kredensial klien. Memerlukan TokenResolver kustom. Pendaftaran aplikasi harus berupa aplikasi standar (non-agen). |
Agent 365 yang diaktifkan menggunakan OBO
Agen yang diaktifkan Agent 365 menerima permintaan dengan identitas agenik (agenticAppId, agenticUserId) dari platform Agent 365. Dengan OBO, komponen bawaan distro AgenticTokenCache menangani akuisisi token secara otomatis : tidak diperlukan resolver token khusus.
Prasyarat
- Pendaftaran aplikasi Entra : Prinsipal layanan (pendaftaran aplikasi) dengan ID Klien, Rahasia Klien, dan ID Penyewa
-
Izin API yang didelegasikan : Tambahkan
Agent365.Observability.OtelWrite(Didelegasikan), berikan persetujuan admin. Untuk langkah-langkah terperinci, lihat Berikan izin.
Penyiapan
Pada setiap siklus, agen Anda memanggil fungsi RegisterObservability dengan konteks giliran. Cache bawaan menggunakan token yang didelegasikan pengguna dari handler AgenticUserAuthorization untuk melakukan pertukaran OBO, memperoleh token dengan cakupan Agent365.Observability.OtelWrite.
Untuk instruksi penyiapan lengkap termasuk paket, konfigurasi, dan contoh kode, lihat Cache token agen dengan aplikasi Agent Framework.
Agent 365 yang diaktifkan menggunakan S2S
Agen yang mendukung Agent 365 juga dapat menggunakan autentikasi S2S (layanan ke layanan) alih-alih OBO. Agen memperoleh token menggunakan identitas prinsipal layanannya sendiri melalui rantai identitas agen dua langkah:
-
getAgenticApplicationToken(tenantId, agentId): kredensial klien + jalur Federated Managed Identity (FMI) - MSAL
acquireTokenForClientdengan token aplikasi sebagaiclientAssertiondan cakupanapi://9b975845-388f-4429-889e-eab1ef63949c/.default
Catatan
Federated Managed Identity (FMI) adalah arsitektur dengan identitas terkelola berpartisipasi dalam federasi identitas beban kerja melalui kredensial identitas federasi, memungkinkan pertukaran token dan autentikasi tanpa rahasia berdasarkan relasi kepercayaan antar identitas.
Anda harus menyediakan TokenResolver khusus dan mengatur UseS2SEndpoint = true.
Prasyarat
Pendaftaran aplikasi Entra : Prinsipal layanan (pendaftaran aplikasi) dengan ID Klien, Rahasia Klien, dan ID Penyewa
Izin API aplikasi : Tambahkan
Agent365.Observability.OtelWrite(Aplikasi), berikan persetujuan adminAgent365.Observability.OtelWritePeran aplikasi : Prinsipal layanan agen harus memiliki peranOtelWriteyang ditetapkan pada sumber daya Observabilitas Agent 365. Gunakan Agent 365 CLI:a365 setup permissions bot --config-dir "<path-to-config-dir>"Catatan
Propagasi peran mungkin memakan waktu beberapa menit. Kesalahan 401 atau 403 awal dari titik akhir ekspor diharapkan selama periode ini.
Langkah 1: Konfigurasi lingkungan
Contoh kode berikut menampilkan cara menyiapkan pengaturan lingkungan untuk koneksi, penyewa, kredensial klien, dan observability exporter yang diperlukan sebelum mengaktifkan alur token S2S kustom.
Tidak diperlukan handler AgenticUserAuthorization. S2S menggunakan rantai identitas agen manual (get_agentic_application_token + MSAL acquire_token_for_client) untuk mendapatkan token yang memiliki cakupan ke sumber daya observabilitas.
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
Langkah 2: Konfigurasikan distro dengan resolver token kustom
Contoh berikut menampilkan cara mengaktifkan ekspor Agent 365 dan mendaftarkan TokenResolver kustom sehingga eksportir dapat mengambil token S2S untuk setiap agen dan penyewa.
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,
)
Langkah 3: Dapatkan dan simpan token S2S dalam cache
Pada setiap pesan masuk, peroleh token S2S melalui rantai identitas agenik dan simpan dalam cache untuk resolver.
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])
Penting
Alur manual dua langkah (get_agentic_application_token + MSAL acquire_token_for_client) diperlukan untuk S2S.
AgenticUserAuthorization.get_token() mengembalikan token dengan cakupan pada 5a807f24-.../.default (Bot Framework), bukan sumber daya observabilitas api://9b975845-.../.default : titik akhir S2S menolaknya dengan 401 InvalidAudience.
- Gunakan
context.activity.get_agentic_instance_id()danget_agentic_tenant_id()untuk membaca agen dan penyewa dari aktivitas (mengambil darirecipientsesuai konvensi SDK). - Dapatkan dan cache token S2S sebelum membuat span.
BatchSpanProcessorEksportir mungkin di-flush sebelum handler selesai : jika token belum di-cache, ekspor gagal. - Bungkus semua cakupan A365 di
BaggageBuilderagar eksportir tahu untuk agen dan penyewa mana token harus diambil. Tanpa bagasi, span akan dijatuhkan tanpa pemberitahuan dengan pesan "Tidak ada span dengan identitas penyewa/agen yang ditemukan."
Mesin kustom menggunakan OBO
Agen mesin kustom menggunakan pendaftaran aplikasi standar dengan koneksi Azure Bot OAuth, bukan rantai identitas agenik. Dengan OBO, agen memperoleh token pengguna melalui Azure Bot OAuth yang cakupannya sudah diatur ke API observabilitas A365 oleh Layanan Token Bot Framework. Cukup satu getToken atau GetTurnTokenAsync panggilan akan mengembalikan token dengan cakupan yang tepat, sehingga Anda tidak memerlukan exchangeToken.
Prasyarat
Registrasi aplikasi Entra dengan Izin API terdelegasi. Tambahkan Agent365.Observability.OtelWrite (Didelegasikan) dan berikan persetujuan admin
Penting
agentId dalam cache token harus cocok dengan pendaftaran aplikasi ID KLIEN - bukan agenticAppId aktivitas, yang tidak ada untuk agen mesin kustom. URL ekspor menyertakan agentId, dan ketidakcocokan menyebabkan HTTP 403.
Langkah 1: Konfigurasi lingkungan dan aplikasi
Contoh berikut menampilkan cara mengonfigurasi aplikasi dan lingkungan runtime Anda, termasuk nilai koneksi layanan, pengaturan penyewa dan klien, serta pemetaan otorisasi yang diperlukan.
# .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
Penting
load_configuration_from_env mengubah semua kunci variabel lingkungan menjadi huruf besar. Nama handler akan menjadi OBOCONNECTIONPROFILE dan Anda harus merujuknya dengan penulisan huruf yang sama persis dalam pemanggilan auth_handlers dan get_token(). Tidak adanya TYPE menyebabkan Auth handler ... not recognized or not configured saat runtime.
Langkah 2: Konfigurasikan distro untuk OBO
Contoh berikut menampilkan cara mengaktifkan ekspor Agent 365, menjaga eksportir tetap pada titik akhir OBO, dan mendaftarkan TokenResolver kustom yang mengembalikan token terdelegasi selama ekspor.
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,
)
Catatan
Mode OBO memerlukan jwt_authorization_middleware pada aiohttpApplication (yang memvalidasi JWT (JSON Web Token) masuk dari Bot Framework). Jalur S2S/emulator tidak boleh menyertakan middleware ini.
from microsoft_agents.hosting.aiohttp import jwt_authorization_middleware
app = Application(middlewares=[jwt_authorization_middleware])
Langkah 3: Dapatkan token OBO
Contoh berikut menampilkan cara meminta token OBO terdelegasi dari koneksi Azure Bot OAuth yang telah dikonfigurasi, lalu menyimpannya dalam cache berdasarkan klien aplikasi dan penyewa untuk pengekspor.
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
Penting
Prasyarat Portal Azure: Koneksi Azure Bot OAuth bernama oboConnectionProfile harus mengatur Cakupannya ke api://9b975845-388f-4429-889e-eab1ef63949c/Agent365.Observability.OtelWrite. Tanpa pengaturan ini, token hanya berlaku untuk audiens bot sendiri (api://botid-...) dan ekspor gagal dengan HTTP 401 InvalidAudience.
Catatan
AGENT_APP.auth.get_token() langsung mengembalikan token dengan cakupan yang benar—tidak perlu melakukan panggilan exchange_token(). Bot Framework Token Service menangani pertukaran OBO saat cakupan koneksi OAuth menargetkan sumber daya observabilitas A365.
Mesin kustom menggunakan S2S
Agen mesin kustom dapat menggunakan S2S (kredensial klien) untuk memperoleh token aplikasi saja menggunakan kredensial koneksi layanan. Metode ini menggunakan kredensial klien MSAL standar, tidak diperlukan rantai identitas agen.
Prasyarat
-
Pendaftaran aplikasi Azure AD : Harus berupa mesin kustom (standar) aplikasi. Registrasi aplikasi yang diaktifkan Agent 365 tidak diperbolehkan menggunakan
client_credentialsbiasa untuk sumber daya observabilitas (AADSTS82001). -
Izin aplikasi : Tambahkan
Agent365.Observability.OtelWrite(Aplikasi, bukan Didelegasikan), dan berikan persetujuan admin.
Penting
agentId yang digunakan untuk caching harus merupakan ClientId milik ServiceConnection. URL ekspor adalah /observabilityService/tenants/{tenantId}/otlp/agents/{agentId}/traces : ketidakcocokan yang menyebabkan HTTP 403.
Langkah 1: Konfigurasi lingkungan dan aplikasi
Contoh berikut menampilkan cara mengonfigurasi aplikasi dan lingkungan runtime Anda, termasuk nilai koneksi layanan, pengaturan penyewa dan klien, serta pemetaan otorisasi yang diperlukan.
# .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
Langkah 2: Konfigurasikan distro untuk S2S
Contoh berikut menampilkan cara mengaktifkan ekspor Agent 365, mengatur eksportir ke titik akhir S2S, dan mendaftarkan TokenResolver kustom untuk pencarian token selama ekspor.
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,
)
Langkah 3: Dapatkan token S2S
Contoh berikut menunjukkan cara memperoleh token akses aplikasi saja untuk sumber daya observabilitas menggunakan kredensial koneksi layanan, lalu menyimpan token tersebut dalam cache per agen dan penyewa untuk eksportir.
# 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
Langkah 4: Atur baggage untuk ekspor span
Eksportir Agent 365 mengharuskan baggage (ID penyewa dan ID agen) disetel pada konteks span. Tanpanya, eksportir diam-diam menjatuhkan rentang dengan pesan 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])