Feature Request: Enterprise OTel auth — mTLS env vars + dynamic-headers helper (parity with Claude Code)
- Ngôn ngữ chính
- Shell
- Star
- 11.2k
- Fork
- 1.9k
- Merge trung bình
- 14 giờ 16 phút
- Pull request đã merge (30 ngày)
- 6
Mô tả
### Summary
Copilot CLI's OpenTelemetry support (shipped via #2471) authenticates the OTLP
exporter via a static `OTEL_EXPORTER_OTLP_HEADERS` value only. This blocks
production enterprise deployments that need (a) mutual TLS to secured OTel
endpoints, or (b) automatic refresh of expiring auth tokens for Microsoft Entra
ID / managed-identity flows.
The peer product Claude Code already ships both. This request asks for parity.
The "parity with Claude Code" framing has precedent here — #2471 was titled
exactly that, and shipped Copilot CLI's OTel support in v1.0.4. This request
asks for the auth-side parity that the initial scope deferred.
### What Copilot CLI has today
- Native OTLP emission (since v1.0.4, #2471).
- Static `OTEL_EXPORTER_OTLP_HEADERS`, set at process start, never refreshed.
- HTTP/JSON transport only (no protobuf — see #2934).
- The official [Copilot SDK observability docs](https://docs.github.com/copilot/how-tos/copilot-sdk/observability/opentelemetry) document a `TelemetryConfig` object with `otlpEndpoint`, `exporterType` (`"otlp-http"` / `"file"`), `sourceName`, `captureContent` — no `headers` field, no auth surface, no mTLS. The auth gap exists at the SDK API surface too, not just the CLI env-var surface.
### What Claude Code has and Copilot CLI doesn't
#### 1. mTLS via env vars
Claude Code honours the standard OpenTelemetry mTLS configuration env vars.
From their [monitoring docs](https://code.claude.com/docs/en/monitoring-usage#mtls-authentication):
| Protocol | Client certificate variables | CA trust |
|---|---|---|
| `http/protobuf`, `http/json` | `CLAUDE_CODE_CLIENT_CERT`, `CLAUDE_CODE_CLIENT_KEY`, optionally `CLAUDE_CODE_CLIENT_KEY_PASSPHRASE` | `NODE_EXTRA_CA_CERTS` |
| `grpc` | `OTEL_EXPORTER_OTLP_CLIENT_KEY`, `OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE` (plus per-signal variants) | `OTEL_EXPORTER_OTLP_CERTIFICATE` |
The `OTEL_EXPORTER_OTLP_CLIENT_*` and `OTEL_EXPORTER_OTLP_CERTIFICATE` variables
are documented in the
[OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options).
The bundled `@opentelemetry/exporter-trace-otlp-*` packages already support
these at the SDK level — they just aren't surfaced from Copilot CLI.
#### 2. Dynamic headers / token refresh
Claude Code lets administrators configure a script that returns headers as
JSON, run at startup and periodically thereafter (default every 29 minutes).
From their [docs](https://code.claude.com/docs/en/monitoring-usage#dynamic-headers):
```json
// .claude/settings.json
{
"otelHeadersHelper": "/bin/generate_opentelemetry_headers.sh"
}
```
```bash
#!/bin/bash
# Mint a fresh Microsoft Entra Bearer for Azure Monitor every time the helper runs
echo "{\"Authorization\": \"Bearer $(az account get-access-token \
--scope https://monitor.azure.com/.default --query accessToken -o tsv)\"}"
```
The interval is configurable via `CLAUDE_CODE_OTEL_HEADERS_HELPER_DEBOUNCE_MS`.
### Why this matters
Microsoft's recommended path for OTLP ingestion into Azure Monitor /
Application Insights uses **Microsoft Entra Bearer tokens**
([docs](https://learn.microsoft.com/en-us/azure/azure-monitor/containers/opentelemetry-protocol-ingestion)).
Entra access tokens are short-lived (60–90 min by default; up to 24h via
Configurable Token Lifetime policies). Without a refresh mechanism in Copilot
CLI, long-running sessions hit auth failures mid-session.
Today the workaround is for each enterprise to build a per-organisation
OTel-translation bridge that takes a static header from Copilot and exchanges
it for a refreshed Entra Bearer upstream. That is real operational overhead
for what is essentially missing config surface in Copilot CLI itself — the
underlying SDK already supports both auth modes.
The similar request on the VS Code side
([microsoft/vscode#304505](https://github.com/microsoft/vscode/issues/304505))
asks for the same dynamic-headers capability, but the CLI is a distinct entry
point and warrants its own implementation.
### Specific asks (small, well-scoped)
1. **Honour the standard OTel mTLS env vars** in Copilot CLI's OTLP exporter —
`OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE`, `OTEL_EXPORTER_OTLP_CLIENT_KEY`,
`OTEL_EXPORTER_OTLP_CERTIFICATE`, plus per-signal variants
(`OTEL_EXPORTER_OTLP_TRACES_*` / `_METRICS_*` / `_LOGS_*`). The bundled
`@opentelemetry/exporter-trace-otlp-*` packages implement these env vars
per the OpenTelemetry spec — Copilot CLI needs a small wiring change to
thread them into the exporter constructor.
2. **Add a dynamic-headers script hook** — analogous to Claude Code's
`otelHeadersHelper`. A config setting points at a script; the script
outputs a JSON object of headers; runs at startup and on a configurable
interval (suggested default: 29 minutes, matching Claude Code). HTTP
transport only (matches Claude Code's design).
### Why it's small
Both asks pass through existing OpenTelemetry SDK functionality. The first is
a small wiring change in the exporter setup. The second is a small wrapper
that periodically execs a script and rebuilds the exporter's headers —
Claude Code's implementation is the existing reference design.
### Related
- #2934 — Support protobuf OTLP export (related transport-side gap).
- [microsoft/vscode#304505](https://github.com/microsoft/vscode/issues/304505) — Same feature request, VS Code side.
- [Ingest OTLP into Azure Monitor](https://learn.microsoft.com/en-us/azure/azure-monitor/containers/opentelemetry-protocol-ingestion).
- [Claude Code — Monitoring](https://code.claude.com/docs/en/monitoring-usage).
- [OTel specification — Exporter configuration](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options).
Hướng dẫn đóng góp
Đánh giá
Issue này chưa được đánh giá.