Skip to content

Teams app#801

Open
clarked-msft wants to merge 78 commits intomicrosoft:Developmentfrom
clarked-msft:teams-app
Open

Teams app#801
clarked-msft wants to merge 78 commits intomicrosoft:Developmentfrom
clarked-msft:teams-app

Conversation

@clarked-msft
Copy link
Copy Markdown
Contributor

No description provided.

The current implementatoin is only for Teams so it's not consistent
across the app.  There's also no way to configure the expected origin,
which means you would be able to run this app behind a proxy or in
kubernetes.  Holding off for more robust implementation.
Copilot AI review requested due to automatic review settings March 19, 2026 11:26
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds Microsoft Teams app + Teams SSO (OBO flow) support to SimpleChat, along with deployment/config updates and documentation so the app can be embedded and authenticated inside the Teams client.

Changes:

  • Add a Teams-aware login experience (login.html) and a new backend token exchange endpoint for Teams SSO (/auth/teams/token-exchange).
  • Introduce Teams SSO configuration/env vars and adjust security headers + session cookie settings to support iframe embedding.
  • Add Teams app packaging assets (manifest template + icons), docs/how-to guidance, and update release notes + bicep deployment parameters.

Reviewed changes

Copilot reviewed 9 out of 13 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
docs/how-to/teams_app.md New how-to for configuring Teams app + SSO, env vars, and troubleshooting.
docs/explanation/release_notes.md Release notes entry for Teams app/SSO and bicep fix.
deployers/bicep/main.bicep Adds enableTeamsSso param; updates ACR suffix to environment-driven value.
deployers/bicep/modules/appService.bicep Wires enableTeamsSso into app settings (ENABLE_TEAMS_SSO).
application/teams_app/manifest.template.json Template Teams manifest for SSO-enabled tab.
application/teams_app/color.png / outline.png Teams app icon assets.
application/single_app/templates/login.html New Teams detection + SSO login page with fallback to normal AAD auth.
application/single_app/static/js/MicrosoftTeams.min.js Bundled Teams JS SDK for offline/disconnected scenarios.
application/single_app/route_frontend_authentication.py Adds Teams login routing behavior + token exchange endpoint.
application/single_app/config.py Adds Teams SSO config + CSP frame-ancestors behavior; version bump.
application/single_app/app.py Sets cookie attributes needed for Teams iframe embedding when Teams SSO enabled.
.gitignore Ignores a generated application/teams_app/manifest.json.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 19, 2026 11:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds Microsoft Teams app packaging + SSO support to SimpleChat, wiring a Teams-aware login experience into the existing Flask/MSAL auth flow and updating deployment/config/docs accordingly.

Changes:

  • Added Teams-aware login.html + local Teams JS SDK and a new /auth/teams/token-exchange endpoint for OBO token exchange.
  • Introduced Teams SSO configuration knobs (ENABLE_TEAMS_SSO, CSP frame-ancestors handling, session cookie settings).
  • Added Teams app package templates/assets + deployment plumbing (Bicep param + env var) and documentation/release notes.

Reviewed changes

Copilot reviewed 9 out of 13 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
docs/how-to/teams_app.md New how-to guide for Teams app + SSO configuration and troubleshooting.
docs/explanation/release_notes.md Release notes entry for Teams SSO + related infra changes.
deployers/bicep/modules/appService.bicep Adds enableTeamsSso param and sets ENABLE_TEAMS_SSO app setting.
deployers/bicep/main.bicep Plumbs enableTeamsSso through and uses az.environment().suffixes.acrLoginServer for ACR suffix.
application/teams_app/manifest.template.json Teams manifest template with SSO-ready webApplicationInfo and tab URLs.
application/teams_app/color.png Teams app icon asset.
application/teams_app/outline.png Teams app outline icon asset.
application/single_app/templates/login.html New Teams-aware sign-in page that attempts Teams SSO and falls back to standard login.
application/single_app/static/js/MicrosoftTeams.min.js Vendored Teams JS SDK for disconnected environments.
application/single_app/route_frontend_authentication.py Adds Teams SSO branching in /login and implements /auth/teams/token-exchange.
application/single_app/config.py Version bump + Teams SSO env vars + CSP frame-ancestors composition and conditional X-Frame-Options.
application/single_app/app.py Adjusts session cookie settings for iframe embedding when Teams SSO is enabled.
.gitignore Ignores generated application/teams_app/manifest.json.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 19, 2026 11:47
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds Microsoft Teams app packaging + documentation and wires up Teams SSO (OBO flow) into the existing Flask auth flow, alongside a small Bicep improvement for ACR suffix portability.

Changes:

  • Introduces Teams SSO login flow (/login Teams-detecting page + /auth/teams/token-exchange OBO endpoint) and adjusts cookies/CSP to support iframe embedding.
  • Adds Teams app package assets (manifest template + icons) and a how-to guide for setup/troubleshooting.
  • Updates Bicep to use az.environment().suffixes.acrLoginServer and adds an enableTeamsSso deployment parameter.

Reviewed changes

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

Show a summary per file
File Description
docs/how-to/teams_app.md New how-to guide for Teams SSO configuration and troubleshooting.
docs/explanation/release_notes.md Release notes entry for Teams integration + Bicep fix.
deployers/bicep/modules/appService.bicep Adds enableTeamsSso param and sets ENABLE_TEAMS_SSO app setting.
deployers/bicep/main.bicep Plumbs enableTeamsSso parameter; uses environment-derived ACR suffix.
application/teams_app/outline.png Teams app outline icon asset.
application/teams_app/color.png Teams app color icon asset.
application/teams_app/manifest.template.json Teams manifest template configured for tab + SSO fields.
application/single_app/templates/login.html New Teams-aware login page that attempts Teams SSO then falls back.
application/single_app/static/js/MicrosoftTeams.min.js Bundled Teams JS SDK for disconnected environments.
application/single_app/route_frontend_authentication.py Implements Teams login branching and token-exchange endpoint.
application/single_app/config.py Adds Teams SSO config/env vars and CSP frame-ancestors handling; bumps version.
application/single_app/app.py Sets session cookie attributes for Teams iframe compatibility when enabled.
.gitignore Ignores generated Teams manifest.json.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 19, 2026 12:00
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds Microsoft Teams tab packaging + Teams SSO (OBO) support to SimpleChat, including deployment toggles, CSP/cookie adjustments for iframe embedding, and documentation/templates for configuring the Teams app.

Changes:

  • Adds Teams SSO login UX (/login?teams=true) and a backend token-exchange endpoint (/auth/teams/token-exchange) using MSAL OBO.
  • Updates security headers and session cookie settings to support Teams iframe embedding.
  • Adds Teams app packaging assets (manifest template + icons) and how-to documentation; updates Bicep and release notes.

Reviewed changes

Copilot reviewed 9 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
docs/how-to/teams_app.md New how-to guide for Teams app + SSO configuration.
docs/explanation/release_notes.md Release notes entry for Teams app/SSO and Bicep ACR suffix fix.
deployers/bicep/modules/appService.bicep Adds enableTeamsSso param and sets ENABLE_TEAMS_SSO app setting.
deployers/bicep/main.bicep Plumbs enableTeamsSso into app service module; fixes ACR suffix via az.environment().suffixes.acrLoginServer.
application/teams_app/manifest.template.json Teams manifest template for packaging a personal tab with SSO fields.
application/teams_app/color.png Teams app icon asset (color).
application/teams_app/outline.png Teams app icon asset (outline).
application/single_app/templates/login.html New Teams-aware login page that attempts Teams SSO then falls back to standard Azure AD.
application/single_app/static/js/MicrosoftTeams.min.js Bundled Teams JS SDK for offline/disconnected environments.
application/single_app/route_frontend_authentication.py Adds Teams SSO entry path and /auth/teams/token-exchange endpoint.
application/single_app/config.py Adds Teams SSO env vars; updates CSP frame-ancestors; bumps version.
application/single_app/app.py Sets SameSite=None/Secure/HttpOnly session cookie flags when Teams SSO is enabled.
.gitignore Ignores generated application/teams_app/manifest.json.

@Bionic711 Bionic711 self-requested a review April 1, 2026 20:16
@Bionic711
Copy link
Copy Markdown
Collaborator

@clarked-msft Could you resolve the conflicts so I can review?

@clarked-msft
Copy link
Copy Markdown
Contributor Author

@clarked-msft Could you resolve the conflicts so I can review?

Fixed... release_notes probably needs work. Looks like merge conflicts had previously been merged to Development.

Copilot AI review requested due to automatic review settings April 10, 2026 12:43
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds Microsoft Teams “tab app” support for SimpleChat with Teams SSO (OBO) login flow, plus deployment knobs and documentation so the app can be embedded in Teams and authenticate seamlessly.

Changes:

  • Introduces a Teams-aware /login experience and a new /auth/teams/token-exchange endpoint to perform MSAL OBO token exchange.
  • Adds Teams SSO configuration and CSP/session-cookie adjustments for iframe embedding, plus a Bicep parameter to toggle Teams SSO.
  • Adds Teams app manifest/icon templates and documentation, and updates release notes.

Reviewed changes

Copilot reviewed 9 out of 13 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
docs/how-to/teams_app.md New how-to guide for configuring Teams app + SSO prerequisites/troubleshooting.
docs/explanation/release_notes.md Documents Teams SSO feature + related deployment changes (currently duplicated in-file).
deployers/bicep/modules/appService.bicep Adds enableTeamsSso param and wires ENABLE_TEAMS_SSO app setting.
deployers/bicep/main.bicep Adds enableTeamsSso param + uses az.environment().suffixes.acrLoginServer for ACR suffix.
application/teams_app/manifest.template.json Adds Teams manifest template placeholders for HOSTNAME/CLIENT_ID.
application/teams_app/color.png Teams app icon asset.
application/teams_app/outline.png Teams app icon asset.
application/single_app/templates/login.html New Teams-detecting login page with SSO + fallback to standard Azure AD login.
application/single_app/static/js/MicrosoftTeams.min.js Vendored Teams JS SDK for offline/disconnected environments.
application/single_app/route_frontend_authentication.py Adds Teams-aware login path + token-exchange endpoint.
application/single_app/config.py Adds Teams SSO env vars and updates CSP/X-Frame-Options behavior for Teams embedding.
application/single_app/app.py Sets session cookie attributes required for cross-origin iframe scenarios when Teams SSO enabled.
.gitignore Ignores application/teams_app/manifest.json (generated/customized manifest).

Comment on lines +331 to +348
* **Microsoft Teams App Integration with SSO**
* Added full Microsoft Teams application support with Single Sign-On (SSO) using the On-Behalf-Of (OBO) flow. Users embedded in Teams are automatically authenticated without a separate login.
* New `/auth/teams/token-exchange` backend endpoint exchanges Teams SSO tokens for access tokens via MSAL OBO flow, with session persistence and activity logging.
* New `login.html` template with Teams SDK detection, automatic SSO authentication, consent-required handling, and graceful fallback to standard Azure AD login.
* Teams manifest template (`manifest.template.json`) with SSO-ready `webApplicationInfo`, static tab, and valid domain configuration.
* New environment variables: `TEAMS_FRAME_ANCESTORS`, `CUSTOM_TEAMS_ORIGINS`, and `ENABLE_TEAMS_SSO` for configurable Teams SSO behaviour.
* Content Security Policy `frame-ancestors` directive now dynamically includes Teams domains via `TEAMS_FRAME_ANCESTORS` setting.
* Session cookies updated to `SameSite=None`, `Secure=True`, `HttpOnly=True` to support cross-origin Teams iframe embedding.
* (Ref: `route_frontend_authentication.py`, `login.html`, `config.py`, `app.py`, `manifest.template.json`, Teams SSO, OBO flow)

* **Teams App Manifest and Icons**
* Added Teams app package files: `manifest.template.json`, `color.png` (192×192), and `outline.png` (32×32) under `application/teams_app/`.
* Template manifest includes placeholders for hostname, client ID, and Application ID URI for easy customisation per deployment.
* (Ref: `application/teams_app/`, Teams app packaging)

* **Teams App Configuration Documentation**
* Comprehensive how-to guide covering Azure AD app registration for Teams SSO, pre-authorised Teams client IDs, environment variables, manifest configuration, testing steps, and troubleshooting.
* (Ref: `docs/how-to/teams_app.md`)
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

The Teams SSO feature block is duplicated in two different places in the release notes (once under v0.241.006 at the top, and again later in the file). This makes the changelog confusing and risks the same content being maintained in multiple spots; keep a single entry in the appropriate version section and remove the duplicate block.

Copilot uses AI. Check for mistakes.
Comment on lines +214 to +217
ENABLE_TEAMS_SSO = os.getenv("ENABLE_TEAMS_SSO", "false").lower() == "true"
TEAMS_FRAME_ANCESTORS = os.getenv("TEAMS_FRAME_ANCESTORS", "") # e.g. "https://teams.microsoft.com https://*.teams.microsoft.com" - should be set to Teams domains if in airgap, otherwise can be left blank to allow from any domain since we validate the origin in the frontend against allowed Teams domains
CUSTOM_TEAMS_ORIGINS_RAW = os.getenv("CUSTOM_TEAMS_ORIGINS", "") # JSON array of valid domains for Teams SSO if in airgap, otherwise this is pulled from Teams, e.g. ["https://teams.microsoft.com", "https://*.teams.microsoft.com"]
CUSTOM_TEAMS_ORIGINS = json.loads(CUSTOM_TEAMS_ORIGINS_RAW) if CUSTOM_TEAMS_ORIGINS_RAW else []
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

The comment on TEAMS_FRAME_ANCESTORS says it can be left blank to allow framing from any domain, but the CSP is always built as frame-ancestors 'self' {TEAMS_FRAME_ANCESTORS}; so a blank value will only allow 'self' and will block Teams iframe embedding. Either require/populate TEAMS_FRAME_ANCESTORS when ENABLE_TEAMS_SSO is true (especially for AZURE_ENVIRONMENT=="custom"), or update the comment/logic so the behavior matches the guidance.

Copilot uses AI. Check for mistakes.
Comment on lines +245 to +247
data = request.get_json()
teams_token = data.get('token') or {}

Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

request.get_json() can return None (missing/invalid JSON body or wrong Content-Type). The next line calls data.get(...), which will raise and return a 500. Handle a non-dict JSON body explicitly and return a 400 with a clear error instead of falling into the generic exception handler.

Suggested change
data = request.get_json()
teams_token = data.get('token') or {}
data = request.get_json(silent=True)
if not isinstance(data, dict):
return jsonify({
"error": "invalid_request",
"error_description": "Request body must be a valid JSON object."
}), 400
teams_token = data.get("token")

Copilot uses AI. Check for mistakes.
Comment on lines +268 to +275
# Store user identity info from ID token claims
session["user"] = result.get("id_token_claims")

# Save the token cache to session
_save_cache(msal_app.token_cache)

user_name = session['user'].get('name', 'Unknown')
log_event(f"Teams SSO: User {user_name} authenticated successfully.")
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

This endpoint assumes result.get("id_token_claims") exists and is a dict, but config.SCOPE is Graph-only (no openid/profile/email), so the OBO result may not include ID token claims. If session["user"] becomes None, session['user'].get(...) will throw and the login will fail. Populate session user data from a reliable source (e.g., decode the incoming Teams JWT assertion claims, or call Graph /me with the acquired access token) and guard against missing claims.

Copilot uses AI. Check for mistakes.
Comment on lines +260 to +266
if "error" in result:
error_description = result.get("error_description", result.get("error"))
log_event(f"Teams token exchange failure: {error_description}", exceptionTraceback=True)
return jsonify({
"error": result.get("error"),
"error_description": error_description
}), 400
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

log_event(..., exceptionTraceback=True) is used here on a non-exception error path and with the default INFO level, which can emit misleading NoneType: None tracebacks. Log this as an error-level event (and include structured properties like MSAL error code/description) without forcing an exception traceback unless you’re inside an actual exception handler.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +30
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sign In - {{ app_settings.app_title or 'SimpleChat' }}</title>
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
<link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap-icons.min.css') }}">
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.login-container {
text-align: center;
max-width: 420px;
width: 100%;
padding: 3rem;
background: white;
border-radius: 12px;
box-shadow: 0 10px 40px rgba(0,0,0,0.2);
}
.logo-section {
margin-bottom: 2rem;
}
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

This PR introduces a new login.html page and client-side authentication flow (Teams detection + fallback) but doesn’t add/update any Playwright UI coverage. Add a UI test under ui_tests/ that at least validates the login page renders, the loading/error states toggle correctly, and the non-Teams fallback path is reachable (e.g., /login?teams=false).

Copilot generated this review using guidance from repository custom instructions.
Comment on lines +249 to +272
# Security Headers Configuration
SECURITY_HEADERS = {
'X-Content-Type-Options': 'nosniff',
'X-XSS-Protection': '1; mode=block',
'Referrer-Policy': 'strict-origin-when-cross-origin',
'Content-Security-Policy': (
"default-src 'self'; "
"script-src 'self' 'unsafe-inline' 'unsafe-eval'; "
#"script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net https://code.jquery.com https://stackpath.bootstrapcdn.com; "
"style-src 'self' 'unsafe-inline'; "
#"style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://stackpath.bootstrapcdn.com; "
"img-src 'self' data: https: blob:; "
"font-src 'self'; "
#"font-src 'self' https://cdn.jsdelivr.net https://stackpath.bootstrapcdn.com; "
"connect-src 'self' https: wss: ws:; "
"media-src 'self' blob:; "
"object-src 'none'; "
f"frame-ancestors 'self' {TEAMS_FRAME_ANCESTORS}; "
"base-uri 'self';"
)
}

if not ENABLE_TEAMS_SSO:
SECURITY_HEADERS['X-Frame-Options'] = 'DENY' # Prevent framing if Teams SSO is not enabled
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

This PR includes runtime and deployer changes (not just docs), but VERSION in config.py is still 0.241.006. Repo instructions require bumping only the 3rd segment after code changes; please increment the version (e.g., to 0.241.007) and keep release notes aligned.

Copilot uses AI. Check for mistakes.
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.

3 participants