Skip to content

[Bug]: Make App.token_provider tenant defaults scope-aware #534

Description

Bug Description

The new public App.token_provider.get_app_token(scope, tenant_id=None) API delegates tenant resolution to TokenManager.get_app_token(). When neither the caller nor configured credentials supplies a tenant, TokenManager falls back to the cloud's Bot Framework login tenant (botframework.com in public cloud), regardless of the requested scope.

That fallback is correct for Bot Framework tokens, but can select the wrong authority for Microsoft Graph or another resource. The app's internal Graph path separately resolves input tenant -> credentials tenant -> "common", so internal and public acquisition behavior diverges.

This concerns the new API proposed in PR #530; it is not a regression in an API currently available on main.

Steps to Reproduce

  1. Configure an App with multi-tenant client credentials and no tenant_id.
  2. Request a non-Bot-Framework token:
    token = await app.token_provider.get_app_token(app.cloud.graph_scope)
  3. Observe that MSAL is initialized with the authority tenant botframework.com rather than the Graph fallback used by App.get_app_graph().

Expected Behavior

Tenant resolution should be explicit and consistent for the requested resource. At minimum:

  • Bot Framework scope: input tenant -> credentials tenant -> cloud.login_tenant.
  • Graph scope: input tenant -> credentials tenant -> "common", preserving existing Graph behavior.
  • Other scopes: either require an explicit/configured tenant or define and document a safe fallback.

The resolution logic should live in one place so public App.token_provider and internal app token acquisition cannot disagree.

Actual Behavior

All calls through App.token_provider.get_app_token() without an explicit or configured tenant fall back to cloud.login_tenant, including non-Bot-Framework scopes.

SDK Version

Unreleased Agent365 token-provider surface in PR #530.

Python Version

Python 3.11-3.14.

Additional Context

Relevant code:

  • packages/apps/src/microsoft_teams/apps/token_provider.py: public provider delegation.
  • packages/apps/src/microsoft_teams/apps/token_manager.py: generic fallback to cloud.login_tenant.
  • packages/apps/src/microsoft_teams/apps/app.py: separate Graph fallback to DEFAULT_TENANT_FOR_GRAPH_TOKEN ("common").

Add a regression test that observes the resolved authority for a multi-tenant non-Bot-Framework request rather than mocking TokenManager entirely.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions