Skip to content

Add agentic auth provider infrastructure#485

Merged
heyitsaamir merged 1 commit into
feature_agent365_supportfrom
add_agentic_auth_infra
Jun 24, 2026
Merged

Add agentic auth provider infrastructure#485
heyitsaamir merged 1 commit into
feature_agent365_supportfrom
add_agentic_auth_infra

Conversation

@heyitsaamir

@heyitsaamir heyitsaamir commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

Adds agentic auth provider plumbing to the API layer.

ApiClient is powered by HttpClient to make requests. Normally, HttpClient can take a token directly, but Agent ID calls need the SDK to choose between a regular bot token and an agentic identity token per request.

So this PR does the following:

  1. Introduces the AgenticIdentity model.
  2. Introduces an AuthProvider concept at the ApiClient layer. If provided, auth can happen through ApiClient if HttpClient does not have a token revolver.
  3. Installs an HTTP interceptor from ApiClient. The interceptor skips requests that already have Authorization, otherwise it uses the AuthProvider.
  4. Uses httpx request extensions to mark per-request AgenticIdentity metadata. This is local-only metadata, not a header, so it does not leak to Teams endpoints. With this, we are basically stamping a request that requires agentic identity.
  5. The interceptor reads that extension, picks the bot vs Agent ID scope, and passes the scope + identity to the AuthProvider.
  6. Updates token-provider typing so custom token providers can receive AgenticIdentity when needed.
  7. Sovereign cloud Agent ID scopes are TODO-marked until platform values are confirmed. No sneaky magic there.

@heyitsaamir

heyitsaamir commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator Author

@heyitsaamir heyitsaamir force-pushed the add_agentic_auth_infra branch 2 times, most recently from c42fdca to 3d65157 Compare June 22, 2026 19:15
@heyitsaamir heyitsaamir requested a review from Copilot June 22, 2026 19:20
Base automatically changed from add_inbound_token_validation to feature_agent365_support June 22, 2026 19:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds “agentic auth provider” infrastructure across the SDK so API calls can obtain the correct token automatically (bot vs Agentic Identity), rather than requiring callers to always pre-wire an HTTP client token callback.

Changes:

  • Introduces an AgenticIdentity model and exposes it via the activity Account model.
  • Adds an AuthProvider protocol plus an HTTP interceptor to inject Authorization when missing, and wires it through ApiClient/subclients; apps get an AppAuthProvider backed by TokenManager.
  • Expands token-provider signatures to optionally accept agentic_identity, and adds an inbound activity token validator that routes between Bot Framework and Entra token validation.

Reviewed changes

Copilot reviewed 29 out of 29 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/common/tests/test_client.py Adds tests ensuring interceptors are exposed read-only and cloned independently.
packages/common/src/microsoft_teams/common/http/client.py Exposes interceptors and adjusts clone behavior around interceptor copying.
packages/apps/tests/test_token_validator.py Adds tests for InboundActivityTokenValidator routing/caching and error cases.
packages/apps/tests/test_token_manager.py Adds tests for agentic identity propagation into token providers and AppAuthProvider behavior.
packages/apps/src/microsoft_teams/apps/token_manager.py Adds app-token API, agentic identity token-provider support, and signature-aware token-provider invocation.
packages/apps/src/microsoft_teams/apps/options.py Switches app options token typing to shared TokenProvider.
packages/apps/src/microsoft_teams/apps/http/http_server.py Switches inbound auth validation to InboundActivityTokenValidator.
packages/apps/src/microsoft_teams/apps/auth/token_validator.py Adds InboundActivityTokenValidator, Entra v1 issuer constant, and bounded validator caching.
packages/apps/src/microsoft_teams/apps/auth/init.py Exports InboundActivityTokenValidator.
packages/apps/src/microsoft_teams/apps/auth_provider.py Adds AppAuthProvider that uses TokenManager for app vs agentic tokens.
packages/apps/src/microsoft_teams/apps/app.py Wires ApiClient to use auth_provider rather than an HTTP-client token override.
packages/apps/pyproject.toml Bumps cryptography minimum version.
packages/api/tests/unit/test_user_client.py Verifies user client uses auth provider to mint bot tokens.
packages/api/tests/unit/test_bot_client.py Adds token-provider signature compatibility tests and auth-provider sign-in test.
packages/api/tests/unit/test_base_client.py Adds tests for interceptor precedence and agentic identity scope selection.
packages/api/src/microsoft_teams/api/models/agentic_identity.py Introduces AgenticIdentity model (API layer).
packages/api/src/microsoft_teams/api/models/account.py Adds agentic identity fields and helper property to build AgenticIdentity.
packages/api/src/microsoft_teams/api/models/init.py Exports AgenticIdentity.
packages/api/src/microsoft_teams/api/clients/user/token_client.py Threads auth_provider/cloud into user token client via BaseClient.
packages/api/src/microsoft_teams/api/clients/user/client.py Threads auth_provider/cloud into UserClient and its subclient.
packages/api/src/microsoft_teams/api/clients/bot/token_client.py Updates deprecated bot token client to support token-provider signatures with optional agentic arg.
packages/api/src/microsoft_teams/api/clients/bot/sign_in_client.py Threads auth_provider/cloud into sign-in client via BaseClient.
packages/api/src/microsoft_teams/api/clients/bot/client.py Threads auth_provider into BotClient subclient construction.
packages/api/src/microsoft_teams/api/clients/base_client.py Adds AuthProvider protocol, attaches auth-provider interceptor, and provides agentic token factory helper.
packages/api/src/microsoft_teams/api/clients/api_client.py Adds auth_provider plumbing into ApiClient and relevant subclients.
packages/api/src/microsoft_teams/api/clients/_auth_provider_interceptor.py Adds request interceptor that injects Authorization via the auth provider when absent.
packages/api/src/microsoft_teams/api/auth/credentials.py Defines TokenProvider typing to allow optional agentic_identity (positional or keyword).
packages/api/src/microsoft_teams/api/auth/cloud_environment.py Adds agentic_bot_scope to cloud environments.
packages/api/src/microsoft_teams/api/auth/init.py Exports new token-provider typing aliases.

Comment thread packages/common/src/microsoft_teams/common/http/client.py Outdated
Comment thread packages/apps/src/microsoft_teams/apps/token_manager.py Outdated
@heyitsaamir heyitsaamir force-pushed the feature_agent365_support branch from 2958451 to 0addde5 Compare June 22, 2026 19:27
@heyitsaamir heyitsaamir changed the base branch from feature_agent365_support to add_inbound_token_validation June 22, 2026 19:27
@heyitsaamir heyitsaamir changed the base branch from add_inbound_token_validation to feature_agent365_support June 22, 2026 19:35
@heyitsaamir heyitsaamir force-pushed the add_agentic_auth_infra branch 2 times, most recently from 5090e99 to 70506df Compare June 22, 2026 19:53
@heyitsaamir heyitsaamir requested a review from Copilot June 22, 2026 22:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated 5 comments.

Comment thread packages/api/src/microsoft_teams/api/clients/base_client.py Outdated
Comment thread packages/api/src/microsoft_teams/api/clients/_auth_provider_interceptor.py Outdated
Comment thread packages/api/src/microsoft_teams/api/clients/bot/sign_in_client.py Outdated
Comment thread packages/api/src/microsoft_teams/api/clients/user/token_client.py Outdated
Comment thread packages/api/src/microsoft_teams/api/clients/base_client.py Outdated
@heyitsaamir heyitsaamir force-pushed the add_agentic_auth_infra branch from 70506df to e2b8163 Compare June 22, 2026 22:39
@heyitsaamir heyitsaamir requested review from corinagum and lilyydu June 22, 2026 23:05
@MehakBindra

Copy link
Copy Markdown
Member

Q: Can the "agentic vs bot" decision live in one place (the TokenManager) rather than three?

Right now the choice of agentic token vs app/bot token - which is purely agentic_identity is None? - seems to be made in three spots that have to stay in sync:

BaseClient._get_auth_token picks agentic_bot_scope + passes the identity when one exists
AuthProviderInterceptor hardcodes bot_scope with no identity (the fallback/no-identity branch)
AppAuthProvider.token re-branches on agentic_identity is None to call get_app_token vs get_agentic_token
So the same boolean is computed in _get_auth_token, recomputed in AppAuthProvider, and the third case is baked into the interceptor — and scope selection (bot_scope vs agentic_bot_scope) is split between the API layer and the cloud config instead of sitting next to the minting logic.

Could the upstream layers just pass the identity (or None) and let TokenManager own the decision - i.e. a single get_token(scope_resource, identity) that internally chooses the bot vs agentic scope/tenant/mint path? The interceptor would then just be the identity=None case rather than a separate hardcoded branch.

@heyitsaamir

Copy link
Copy Markdown
Collaborator Author

Hm, yeah it's a bit unclear.

Basically the way .net does this is when an api is called with agentic identity set to true, it sets a signal saying "hey this method will require an agentic identity token to be minted". And then before sending, the right token is minted in the authentication provider.

In python there is no equivalent way to say "hey this request will require an agentic identity token to be minted" later on. Instead of that, we pass in a token override if identity already exists. If there's no override, it falls back to the authprovider's basic bot-token minting (which uses the default bot-scope).
(Maybe this can be cleaner and that would help simplify the design).

What you're suggesting is already being done by the auth provider.
image

The token manager is a layer above, and just cares about token minting, so I think the authprovider is the right place to put this branching.

But you're right the token overriding is a bit messy. Let me see if I can remove the token-overriding in favor of just stamping a request with agentic identity instead.

@heyitsaamir heyitsaamir force-pushed the add_agentic_auth_infra branch from e2b8163 to cfdbefa Compare June 23, 2026 04:07
@heyitsaamir

Copy link
Copy Markdown
Collaborator Author

Update: @MehakBindra - check the latest update. Here we're doing something similar as .net. Methods with agentic identity would stamp the request using extension and a set key. (see #478 for eg). Then, the interceptor would check if "Authentication" headers were already set. If not, it would call the auth provider. I think the logic is pretty simple now. Thoughts?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated 1 comment.

Comment on lines +137 to +139
assert client.interceptors == (interceptor1,)
assert clone.interceptors == (interceptor1, interceptor2)
assert client.interceptors is not clone.interceptors
Comment thread examples/agent365/src/main.py
Comment thread packages/api/src/microsoft_teams/api/auth/credentials.py
Comment thread packages/api/src/microsoft_teams/api/clients/bot/token_client.py
@heyitsaamir heyitsaamir force-pushed the add_agentic_auth_infra branch from cfdbefa to e102800 Compare June 24, 2026 00:34
@heyitsaamir heyitsaamir force-pushed the add_agentic_auth_infra branch from e102800 to 5f44f4a Compare June 24, 2026 00:43
@heyitsaamir heyitsaamir merged commit f39b58f into feature_agent365_support Jun 24, 2026
9 checks passed
@heyitsaamir heyitsaamir deleted the add_agentic_auth_infra branch June 24, 2026 05:25
heyitsaamir added a commit that referenced this pull request Jun 24, 2026
Adds agentic auth provider plumbing to the API layer.

`ApiClient` is powered by `HttpClient` to make requests. Normally,
`HttpClient` can take a token directly, but Agent ID calls need the SDK
to choose between a regular bot token and an agentic identity token per
request.

So this PR does the following:
1. Introduces the `AgenticIdentity` model.
2. Introduces an `AuthProvider` concept at the `ApiClient` layer. If
provided, auth can happen through `ApiClient` if HttpClient does not
have a token revolver.
3. Installs an HTTP interceptor from `ApiClient`. The interceptor skips
requests that already have `Authorization`, otherwise it uses the
`AuthProvider`.
4. Uses `httpx` request extensions to mark per-request `AgenticIdentity`
metadata. This is local-only metadata, not a header, so it does not leak
to Teams endpoints. With this, we are basically stamping a request that
requires agentic identity.
5. The interceptor reads that extension, picks the bot vs Agent ID
scope, and passes the scope + identity to the `AuthProvider`.
6. Updates token-provider typing so custom token providers can receive
`AgenticIdentity` when needed.
7. Sovereign cloud Agent ID scopes are TODO-marked until platform values
are confirmed. No sneaky magic there.
heyitsaamir added a commit that referenced this pull request Jun 24, 2026
This PR adds `AgenticIdentity` as a new auth context across the Teams
API surface.

Why:
Agent ID calls need a user-shaped Agent ID token instead of the normal
bot token. The API methods now accept `agentic_identity` where needed,
and the shared auth interceptor uses local request metadata to pick the
right auth path.

Interesting bits:
- Adds optional `agentic_identity` to conversation create, activity
operations, conversation members, reactions, teams, and meetings.
- Adds optional `service_url` overrides across the service-url based
APIs touched here.
- Agentic identity is passed through `httpx` request extensions, not
headers. So it stays inside the client pipeline and does not leak to
Teams endpoints.
- The auth interceptor reads that extension and asks the auth provider
for the right token.

Reviewer tips:
Start with the API method signatures, then the changed call sites in
`ConversationActivityClient`, `ConversationMemberClient`,
`ReactionClient`, `TeamClient`, and `MeetingClient`. The auth plumbing
itself lives one PR down in #485.

Testing:
- Focused API unit tests for conversation, reaction, bot, user, team,
and meeting clients.
- Full test suite passed locally.

Live smoke tested with Agent ID token:
- conversation activity create/update/reply/get_members
- conversation members get_all/get/get_paged
- reactions add/delete
- teams get_by_id/get_conversations
- conversations.create
- meetings get_by_id/get_participant

Known limitation:
- targeted activity create/update reached the service but returned 500.
Leaving that as not proven until platform behavior is confirmed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants