feat(msteams): add federated credential support (certificate + managed identity)#53615
feat(msteams): add federated credential support (certificate + managed identity)#53615BradGroux merged 10 commits intoopenclaw:mainfrom
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c3c8dfa94a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Greptile SummaryThis PR adds certificate and Azure Managed Identity authentication paths to the MS Teams integration by refactoring Key findings:
Confidence Score: 3/5
Prompt To Fix All With AIThis is a comment left during a code review.
Path: extensions/msteams/src/sdk.test.ts
Line: 141
Comment:
**`createMSTeamsAdapter` + `continueConversation` test coverage dropped**
The previous `sdk.test.ts` contained a test titled `"provides deleteActivity in proactive continueConversation contexts"` that verified an HTTP `DELETE` was issued via `ctx.deleteActivity` inside the `logic` callback. That test — and the whole import of `createMSTeamsAdapter` — was removed in this PR and not replaced.
`createSendContext` (used by `continueConversation`) still wires up `deleteActivity` via `deleteActivityViaRest`, so the production code path still exists. A coverage gap now exists for the `continueConversation` proactive messaging flow. Consider adding at minimum one test that exercises `createMSTeamsAdapter.continueConversation` and verifies `sendActivity` / `deleteActivity` behavior against a `fetch` mock.
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: extensions/msteams/src/sdk.ts
Line: 101-115
Comment:
**Credential instance recreated on every token call — token cache never reused**
`tokenProvider` creates a brand-new `ManagedIdentityCredential` / `DefaultAzureCredential` instance on every invocation. Each `@azure/identity` credential object maintains its own in-memory token cache; constructing a fresh instance discards that cache, so every call to `tokenProvider` issues a new outbound token request to Azure IMDS or AAD — even when the previous token is still valid.
Under realistic load (one Teams message → one `tokenProvider` call), this results in a new IMDS/AAD round-trip per message. IMDS is rate-limited, and `DefaultAzureCredential` probes multiple credential sources in sequence on each construction, making the overhead significant.
The credential should be created once (lazily, to keep the dynamic import on-demand) and captured in the closure — a module-level promise variable initialised on first call is the standard pattern for this in `@azure/identity` users. Something like:
```typescript
let credentialPromise: Promise<ManagedIdentityCredential | DefaultAzureCredential> | null = null;
const getCredential = async () => {
if (!credentialPromise) {
credentialPromise = import("@azure/identity").then((az) =>
creds.managedIdentityClientId
? new az.ManagedIdentityCredential(creds.managedIdentityClientId)
: new az.DefaultAzureCredential(),
);
}
return credentialPromise;
};
const tokenProvider = async (): Promise<string> => {
const credential = await getCredential();
const token = await credential.getToken(BOT_FRAMEWORK_SCOPE);
if (!token?.token) throw new Error("Failed to acquire token via managed identity.");
return token.token;
};
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: extensions/msteams/src/sdk.ts
Line: 85
Comment:
**Unguarded `readFileSync` surfaces raw filesystem errors**
If `creds.certificatePath` points to a missing or unreadable file, Node.js throws a raw `ENOENT`/`EACCES` error with no context about certificate-based auth. Wrapping the call in a try/catch and re-throwing with a descriptive message (e.g. `"Failed to read certificate file at '${creds.certificatePath}': ${err.message}"`) would produce a much clearer diagnostic for operators configuring this for the first time.
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "Merge origin/main into hdya/teams-authen..." | Re-trigger Greptile |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5a763a2493
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7faecd5659
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
7faecd5 to
3f09bf8
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3f09bf808b
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7e16c60c86
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
7e16c60 to
dbb0fb2
Compare
|
it appears that the MAC OS check error is from main branch |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3ccbc9d5e9
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
3ccbc9d to
f9cd5ea
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f9cd5eafdd
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
f9cd5ea to
718220a
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 718220abb3
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
75e9857 to
1ee45b1
Compare
1ee45b1 to
06716e6
Compare
06716e6 to
802ea3e
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 802ea3e9ee
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
802ea3e to
25279e4
Compare
25279e4 to
698f758
Compare
|
Looks great. The discriminated union for credentials is a solid choice, and I like that existing secret auth stays completely untouched as the default. Certificate and managed identity paths give us proper passwordless auth for production, which is a big step up from rotating client secrets. @HDYA needs rebase due to conflicts. |
…naged identity + workload identity)
b82f81e to
b444b94
Compare
# Conflicts: # src/canvas-host/a2ui/.bundle.hash
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9e93980d83
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const activeRegistry = state?.activeRegistry ?? null; | ||
| if (countChannels(activeRegistry) > 0) { | ||
| return activeRegistry; | ||
| } | ||
| return pinnedRegistry ?? activeRegistry; |
There was a problem hiding this comment.
Keep channel registry version in sync with fallback registry
This function can now return activeRegistry when the pinned channel registry is empty, but getActivePluginChannelRegistryVersionFromState() still reports the pinned channel.version whenever channel.registry exists. That creates a registry/version mismatch and can leave version-keyed caches stale (for example getChatCommands() and getNativeCommandSurfaces() in src/auto-reply/commands-registry.data.ts) after active channel plugins change under a pinned-empty channel surface.
Useful? React with 👍 / 👎.
| id: "discord-rest", | ||
| label: "Discord REST monitor fetch", | ||
| modulePath: "extensions/discord/src/monitor/rest-fetch.ts", | ||
| modulePath: "extensions/discord/monitor/rest-fetch.ts", |
There was a problem hiding this comment.
Restore valid source paths in debug proxy coverage entries
These modulePath values were changed to paths that do not exist in the repo (for example dropping /src/), so openclaw proxy coverage now emits broken source references for multiple seams (discord-rest, discord-gateway, telegram-fetch, mattermost-ws, and feishu-client-*). This regresses the report’s ability to point maintainers to the actual implementation files.
Useful? React with 👍 / 👎.
…d identity) (openclaw#53615) * feat(msteams): add federated authentication support (certificate + managed identity + workload identity) * msteams: fix vitest 4.1.2 compat, type errors, and regenerate config baseline * msteams: fix lint errors, update fetch allowlist, regenerate protocol Swift * fix(msteams): gate secret-only delegated auth flows * fix(ci): unblock gateway watch and install smoke * fix(ci): restore mergeability for pr 53615 * fix(ci): restore channel registry helper typing * fix(ci): refresh raw fetch guard allowlist --------- Co-authored-by: Chudi Huang <Chudi.Huang@microsoft.com> Co-authored-by: Brad Groux <3053586+BradGroux@users.noreply.github.com>
…d identity) (openclaw#53615) * feat(msteams): add federated authentication support (certificate + managed identity + workload identity) * msteams: fix vitest 4.1.2 compat, type errors, and regenerate config baseline * msteams: fix lint errors, update fetch allowlist, regenerate protocol Swift * fix(msteams): gate secret-only delegated auth flows * fix(ci): unblock gateway watch and install smoke * fix(ci): restore mergeability for pr 53615 * fix(ci): restore channel registry helper typing * fix(ci): refresh raw fetch guard allowlist --------- Co-authored-by: Chudi Huang <Chudi.Huang@microsoft.com> Co-authored-by: Brad Groux <3053586+BradGroux@users.noreply.github.com>
…d identity) (openclaw#53615) * feat(msteams): add federated authentication support (certificate + managed identity + workload identity) * msteams: fix vitest 4.1.2 compat, type errors, and regenerate config baseline * msteams: fix lint errors, update fetch allowlist, regenerate protocol Swift * fix(msteams): gate secret-only delegated auth flows * fix(ci): unblock gateway watch and install smoke * fix(ci): restore mergeability for pr 53615 * fix(ci): restore channel registry helper typing * fix(ci): refresh raw fetch guard allowlist --------- Co-authored-by: Chudi Huang <Chudi.Huang@microsoft.com> Co-authored-by: Brad Groux <3053586+BradGroux@users.noreply.github.com>
…d identity) (openclaw#53615) * feat(msteams): add federated authentication support (certificate + managed identity + workload identity) * msteams: fix vitest 4.1.2 compat, type errors, and regenerate config baseline * msteams: fix lint errors, update fetch allowlist, regenerate protocol Swift * fix(msteams): gate secret-only delegated auth flows * fix(ci): unblock gateway watch and install smoke * fix(ci): restore mergeability for pr 53615 * fix(ci): restore channel registry helper typing * fix(ci): refresh raw fetch guard allowlist --------- Co-authored-by: Chudi Huang <Chudi.Huang@microsoft.com> Co-authored-by: Brad Groux <3053586+BradGroux@users.noreply.github.com>
Add alternative authentication methods for Microsoft Teams beyond client secrets. Users can now authenticate using:
ClientCertificateCredential)ManagedIdentityCredential)Changes:
ClientCertificateCredentialfrom@azure/identitywith a custom token callbackManagedIdentityCredentialfrom@azure/identitywith a custom token callbackSummary
MSTeamsCredentialsis now a discriminated union (secret|federated). NewcreateFederatedApp,createCertificateApp, andcreateManagedIdentityAppfactory functions dispatch based on credential type. Credential instances are lazily created and cached for token reuse. Zod schema extended with optional fields.appId + appPassword + tenantIdsecret-based auth path is untouched. Default behavior (noauthTypeconfigured) resolves to"secret"— fully backward compatible.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Root Cause / Regression History (if applicable)
N/A — this is a new feature, not a bug fix.
Regression Test Plan (if applicable)
extensions/msteams/src/sdk.test.ts,extensions/msteams/src/token.test.tsClientCertificateCredentialfor token acquisitionManagedIdentityCredentialwith lazy cachinguseManagedIdentity: falseoverrides envMSTEAMS_USE_MANAGED_IDENTITY=trueUser-visible / Behavior Changes
authType,certificatePath,certificateThumbprint,useManagedIdentity,managedIdentityClientIdMSTEAMS_AUTH_TYPE,MSTEAMS_CERTIFICATE_PATH,MSTEAMS_CERTIFICATE_THUMBPRINT,MSTEAMS_USE_MANAGED_IDENTITY,MSTEAMS_MANAGED_IDENTITY_CLIENT_IDappId + appPasswordconfigs continue working without modificationSecurity Impact (required)
ManagedIdentityCredentialfor MI,ClientCertificateCredentialfor certs)Repro + Verification
Environment
authType: "federated",useManagedIdentity: truewith AKS workload identitySteps
authType: "federated"anduseManagedIdentity: trueExpected
Actual
Evidence
Human Verification (required)
useManagedIdentity: falseoverriding env varReview Conversations
Compatibility / Migration
resolveAuthType()defaults to"secret"when not configuredFailure Recovery (if this breaks)
authTypefrom config (defaults back to secret auth)Risks and Mitigations