End-to-End Post Quantum Cryptography: Messaging Teams Extension
How pQCee’s SafeQuard messaging extension secures messages and attachments without changing how your teams work.
1. The Problem
Microsoft Teams is now the digital workplace for sharing highly sensitive content, everything from banking documents, legal contracts, to customer records in everyday chat and channels. While communications are encrypted in transit using TLS, they aren’t shielded against the growing “harvest now, decrypt later” threat where attackers intercept and store encrypted content today, waiting until future quantum computers can break it. This means that data shared in Teams, could become compromised years later, especially if attackers capture the data before uploading to SharePoint.
2. The Solution
SafeQuard embeds Post-Quantum Cryptography directly into Teams so that messages and attachments are encrypted before they leave the client side (sender and recipients). This means data is secured before it traverses networks or is stored in SharePoint. Using quantum-resistant algorithms (ML-KEM), content remains secure against both current threats and future cryptographic breakthroughs. The encrypted package is stored safely in SharePoint, and only authorized recipients browsing within Teams can decrypt and view it. This eliminates the risks of TLS only transit protection and mitigates “harvest now, decrypt later” while keeping collaboration seamless.
3. How this works
Refer to Figures 1 and 2 for an overview of the user flow. When a sender chooses to encrypt, SafeQuard locally protects the message and or attachments before they leave Teams. The encrypted package is then uploaded to SharePoint, and an Adaptive Card containing the encrypted preview and link is posted in the chat or channel. On the recipient side, clicking Decrypt launches the SafeQuard module, which verifies authorization and decrypts the content directly inside Teams. At no point does sensitive data travel unprotected.
4. Key Screens
5. Lessons Learned When Building a Teams Extension
i. Be Explicit With Data Formats in Cryptography
One issue I faced was inconsistent handling of data formats. The Web Crypto API expects ArrayBuffer / TypedArray (Uint8Array) inputs across its functions (importKey, encrypt, decrypt), but in practice it’s easy to accidentally pass around Base64 strings, Hex strings, or plain text. This causes silent errors during encryption or decryption.
- AES Key: Must be converted to Uint8Array before calling crypto.subtle.importKey.
- AES IV (Initialization Vector): Must also be a Uint8Array when passed into encrypt or decrypt.
- Data input (message or files): If starting from text, encode with TextEncoder. If starting from Base64, decode it into bytes first.
ii. Getting a Graph Token On Behalf Of the User (reference)
When fetching chat-related information (like recipients’ names and emails) from Microsoft Graph, I couldn’t just use the token my Teams app received through SSO because that token is only valid for app’s resource, not for Graph. From the app’s perspective, I could not directly call Graph with it.
To call Graph on behalf of the signed-in Teams user, I had to implement the OAuth 2.0 On-Behalf-Of (OBO) flow. This flow lets my backend exchange the Teams user token for a Graph token that is scoped to https://graph.microsoft.com/.
To make this work, I had to:
a. Configure Azure AD App Registration with delegated Graph permissions (e.g., User.Read).
b. Ensure the resourceUri or scope was set correctly to Graph (https://graph.microsoft.com/).
c. Implement the OBO flow in the backend, where the Teams token is sent as the assertion and Azure AD returns a Graph token.
iii. Adaptive Card Payload Size Limits
Teams enforces a maximum payload size for cards (~28 KB). When I tried embedding encrypted data in the card’s query string, I quickly hit the limit (~2200 characters) and got PayloadTooLargeError. The fix was to pass data inside the card body as a hidden field instead of overstuffing the query string.
iv. Authorizing Microsoft Teams as a Client App (reference)
To enable Teams SSO, you must add the Teams client application IDs into your Azure AD app registration. Without this step, login flows will silently fail. The two IDs you’ll need are:
- 1fec8e78-bce4-4aaf-ab1b-5451cc387264 (Teams desktop and mobile client)
- 5e3ce6c0-2b1f-4285-8d4b-75ee78787346 (Teams web client)
v. Debug Logging in Task Modules (HTML)
Unlike a normal browser, you cannot open DevTools inside a Teams task module. This makes debugging difficult. My workaround was to create a simple API endpoint such as “/log” and send client-side logs there, so I could inspect them externally.
6. Closing
SafeQuard by pQCee is designed for organizations that cannot afford to compromise on security, including banks, law firms, healthcare providers, researchers, and enterprises safeguarding sensitive intellectual property. By embedding post-quantum cryptography directly into Microsoft Teams, SafeQuard ensures that collaboration remains seamless while protecting critical communications not only against today’s threats but also against those of the quantum era.
This project has been an invaluable learning journey for me. I am especially grateful to my supervisor, Jia Sen, and to our CEO, Teik Guan, for their guidance and support throughout the development of this extension during my internship.
Author
Samuel Lam
Lam Yu En (Samuel) is an intern at pQCee. Passionate about post-quantum cybersecurity and end-to-end product development, he contributed to the SafeQuard Teams Messaging Extension and is eager to apply his skills in building quantum-safe solutions while completing his final year of a Computer Science degree at SUTD.