Skip to content

(feat): Use the Azure Identity Auth extension for Geneva GCS authentication #4457

Description

@swashtek

Pre-filing checklist

  • I searched existing issues and didn't find a duplicate

Component(s)

Rust OTAP dataflow (rust/otap-dataflow/)

Is your feature request related to a problem?

The OTAP Geneva exporter currently configures authentication directly on
geneva-uploader. This prevents it from using the existing Azure Identity Auth
extension as the source of the Entra token used to authenticate to Geneva
Config Service.

The Azure Identity Auth extension already owns the concerns that should remain
outside an exporter:

  • identity selection;
  • Entra token acquisition;
  • token caching;
  • refresh scheduling;
  • startup readiness;
  • coalescing concurrent acquisitions;
  • retry and failure backoff; and
  • authentication telemetry.

The Geneva exporter should consume the extension's existing
bearer_token_provider capability and pass the resulting Entra token to
geneva-uploader.

Azure Arc is the initial use case. OTAP's Azure Identity SDK supports the Arc
managed identity flow, but that SDK path performs some synchronous environment
and filesystem operations. Those operations must not run on OTAP's
single-threaded pipeline executor.

Proposed Solution

Integrate the Geneva exporter with the existing Azure Identity Auth extension.

The resulting flow should be:

Azure Identity Auth extension
  - selects the configured identity
  - acquires and refreshes the Entra token
  - exposes the token through bearer_token_provider
                         |
                         v
Geneva exporter adapter
  - obtains the current usable token
  - implements geneva-uploader's token-provider interface
                         |
                         v
geneva-uploader
  - authenticates the GCS request
  - caches the Geneva ingestion credential and routing
  - uploads telemetry

This work depends on the external token-provider API proposed for
geneva-uploader: open-telemetry/opentelemetry-rust-contrib#849

Geneva exporter authentication option

Add an authentication option for externally provided Entra tokens. A possible
configuration shape is:

extensions:
  geneva_identity:
    type: "urn:microsoft:extension:azure_identity_auth"
    config:
      method: managed_identity
      scope: "https://monitor.azure.com/.default"
      startup_timeout: 30s

nodes:
  geneva-exporter:
    type: "urn:microsoft:exporter:geneva"
    capabilities:
      bearer_token_provider: geneva_identity
    config:
      endpoint: "https://example.geneva.endpoint"
      environment: "production"
      account: "example-account"
      namespace: "example-namespace"
      account_routing:
        default_group: "example-account-group"
      region: "example-region"
      config_major_version: 1
      tenant: "example-tenant"
      role_name: "collector"
      role_instance: "collector-01"

      auth:
        type: externaltoken
        resource: "https://monitor.azure.com"

The scope and resource above are examples. Users must configure the values
required by their Geneva environment.

When external-token authentication is selected, the exporter should require a
bearer_token_provider capability binding.

The exporter should fail during construction when:

  • the capability binding is missing;
  • the bound extension does not provide the capability; or
  • the capability is available only as a local implementation.

A shared capability is required because the uploader's provider is
Send + Sync.

Existing Geneva endpoint, region, account, namespace, and routing validation
should continue to apply. External-token mode still uses GCS and should not
inherit the relaxed configuration rules used by agent-fed mode.

Token-provider adapter

Add a small private adapter between OTAP's shared bearer-token capability and
the uploader's token-provider interface.

The adapter should:

  1. Request the current token from BearerTokenProvider.
  2. Reject an empty token.
  3. Reject a token that is expired or within the existing OTAP token usability
    margin, when expiry is known.
  4. Return the token in the secret-wrapped form expected by the uploader.
  5. Propagate capability failures without selecting another identity.

The adapter should not have its own token cache, refresh timer, retry loop, or
background task. Those responsibilities remain with the Azure Identity Auth
extension.

Resource and scope configuration

The uploader provider accepts a resource argument, while OTAP's bearer-token
capability returns a token for the scope configured on the extension.

The adapter should verify that the uploader requested the resource configured
on the Geneva exporter. However, the current capability does not expose its
configured scope, so the exporter cannot prove that the bound extension uses
the corresponding scope.

This limitation should be documented:

  • one Azure Identity Auth extension instance represents one identity and one
    scope;
  • the exporter resource and extension scope must refer to the same target
    service; and
  • a mismatch will ultimately be rejected by GCS.

The exporter should not parse token claims to infer or validate the audience.

Keep agent-fed authentication separate

External-token and agent-fed authentication represent different flows:

  • External-token mode supplies an Entra token and preserves the GCS exchange.
  • Agent-fed mode supplies the final Geneva ingestion token, endpoint, and
    routing snapshot and bypasses GCS.

The new integration should not route external-token authentication through the
agent-fed credential source.

Azure Arc support

Use the existing Azure Identity Auth extension with:

method: managed_identity

The extension and Azure SDK should detect the managed identity environment. The
Geneva exporter should not contain Arc-specific detection or challenge-response
logic.

OTAP's Arc-capable Azure Identity SDK performs synchronous operations during Arc
detection and token acquisition, including filesystem checks and challenge-file
reads. Managed-identity credential construction and acquisition must therefore
be isolated from the pipeline executor.

The implementation should meet the following requirements:

  • synchronous SDK work does not execute on the thread-per-core pipeline
    executor;
  • credential construction is included because environment detection may
    perform filesystem operations;
  • the constructed credential is reused across refreshes;
  • blocking work is bounded before it is submitted;
  • cancellation or timeout of the awaiting caller does not free capacity while
    the blocking work is still running;
  • repeated failures cannot create an unbounded queue of acquisition jobs;
  • the existing extension cache and acquisition coalescing remain in effect;
  • startup readiness and background refresh behavior are preserved;
  • SDK and worker failures are surfaced explicitly; and
  • a new Tokio runtime is not created for every token acquisition.

A bounded spawn_blocking implementation is one option. An equivalent
implementation is acceptable if tests demonstrate that synchronous SDK work
cannot block the pipeline executor or accumulate without a bound.

The execution isolation belongs in the Azure Identity Auth extension, not in
the Geneva adapter. This keeps the extension safe for any component that uses
managed identity, rather than making only the Geneva exporter safe.

Credential lifecycles

The Entra token and Geneva ingestion credential have separate owners and refresh
policies:

Entra token
  Owner: Azure Identity Auth extension
  Refresh: based on Entra token expiry and extension policy

Geneva ingestion credential and routing
  Owner: geneva-uploader
  Refresh: based on the existing GCS cache policy

Refreshing the Entra token should not invalidate a usable Geneva ingestion
credential. The extension should only be consulted when the uploader needs
another GCS exchange.

Alternatives Considered

Acquire Arc tokens directly in the Geneva exporter

This would duplicate identity behavior already provided by the Azure Identity
Auth extension. It would also make the exporter responsible for environment
detection, token caching, refresh scheduling, and SDK execution policy.

Let geneva-uploader acquire the Arc identity

That would make an otherwise reusable uploader responsible for Arc-specific
environment and filesystem behavior. It would also prevent OTAP from reusing
its identity extension across exporters.

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions