Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
156370 stories
·
33 followers

1015: Browsers and UIs are dead. Everything is chat

1 Share

Is the web dead, or just evolving? Wes Bos breaks down his JS Nation Amsterdam talk on agentic interfaces, why chat won’t replace everything, how Web MCP lets agents interact with your existing sites, and what “Clicks and Clankers” really means for the future of UI.

Show Notes

  • 00:00 Intro
  • 00:33 Welcome to Syntax!
  • 00:46 Wes’s Talk: Agentic Interfaces at JS Nation
  • 01:37 Is the Web Dead? Chat vs. Traditional UI
  • 03:13 No UI, Voice UI, and the Smart Home Vision
  • 04:00 What Is Web MCP and How It Works
  • 05:10 Clicks and Clankers: When to Click vs. Prompt
  • 06:57 The Future of Shopping and the Open Web Problem
  • 08:46 Delegating the Boring Stuff: Groceries and Expense Categorization
  • 11:55 MCP Apps and the Happy Path Problem
  • 12:55 Brought to you by Sentry.io
  • 13:23 Generative UI: Can the LLM Make a Better UI Than You?
  • 14:54 Smart Home Dashboards and the Jarvis Dream
  • 17:24 Is the Web Dead? Final Thoughts

Hit us up on Socials!

Syntax: X Instagram Tiktok LinkedIn Threads

Wes: X Instagram Tiktok LinkedIn Threads

Scott: X Instagram Tiktok LinkedIn Threads

Randy: X Instagram YouTube Threads





Download audio: https://traffic.megaphone.fm/FSI6751998324.mp3
Read the whole story
alvinashcraft
just a second ago
reply
Pennsylvania, USA
Share this story
Delete

Three Teams, Three Backlogs, One Feature—Can You Make Them See Each Other? | Olaitan Fashanu

1 Share

Olaitan Fashanu: Three Teams, Three Backlogs, One Feature—Can You Make Them See Each Other?

Read the full Show Notes and search through the world's largest audio library on Agile and Scrum directly on the Scrum Master Toolbox Podcast website: http://bit.ly/SMTP_ShowNotes.

 

"How do we ensure that these teams actually work together to show the same data?" - Olaitan Fashanu

 

Olaitan brings a problem most Scrum Masters in scaled environments will recognize. Three teams. Three separate backlogs. One product, accessed across app, web, and support channels. Leadership made a top-down team topologies decision: split the work to move faster. Predictable result—each team optimizes for their own backlog, blind to what the others are building, sometimes shipping the same feature twice with different behaviors. The product owners know there's overlap. The teams love the idea of linking tickets across backlogs. They just won't maintain the habit. Olaitan and Vasco walk through experiments together: a sync between POs, joint refinement sessions, linking tickets, putting "this is also being built by Team B" notes at the top of stories. The deeper insight: the Scrum Master's job is to keep surfacing information until a habit forms. As Vasco's old lifting coach put it—you find the imbalance, you get rid of the imbalance, one by one. That's how you get stronger.

 

In this episode, we refer to team topologies and the practice of surfacing information across team boundaries.

 

Self-reflection Question: Where in your organization are teams unknowingly building the same thing twice—and what's the smallest experiment you could run this week to make that visible?

 

[The Scrum Master Toolbox Podcast Recommends]

🔥In the ruthless world of fintech, success isn't just about innovation—it's about coaching!🔥

Angela thought she was just there to coach a team. But now, she's caught in the middle of a corporate espionage drama that could make or break the future of digital banking. Can she help the team regain their mojo and outwit their rivals, or will the competition crush their ambitions? As alliances shift and the pressure builds, one thing becomes clear: this isn't just about the product—it's about the people.

 

🚨 Will Angela's coaching be enough? Find out in Shift: From Product to People—the gripping story of high-stakes innovation and corporate intrigue.

 

Buy Now on Amazon

 

[The Scrum Master Toolbox Podcast Recommends]

 

About Olaitan Fashanu

 

Olaitan Fashanu is a customer-focused professional with expertise in product management, technology, and coaching. He drives digital and agile transformation, builds collaborative cross-functional teams, and delivers high-quality products across markets. Curious and strategic, he explores AI and data intelligence while balancing technical depth, business goals, culture, structure, and long-term vision.

 

You can link with Olaitan Fashanu on LinkedIn.

 





Download audio: https://traffic.libsyn.com/secure/scrummastertoolbox/20260624_Olaitan_Fashanu_W.mp3?dest-id=246429
Read the whole story
alvinashcraft
14 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

Post-Quantum Cryptography and Crypto-Agility

1 Share

Introduction

This post focuses on a topic critical to help move to post-quantum cryptographic (PQC) algorithms and that topic is crypto-agility for applications that use cryptography.

This post does not discuss the implications of quantum computers on cryptography; you can read that elsewhere such as:

What is Crypto-Agility?

As NIST explains, crypto-agility is about changing cryptographic algorithms without interrupting the flow of a running system, which is exactly why it is foundational to long-term resilience in the PQC era.

However, crypto-agility is not simply the ability to swap one algorithm for another; it is the engineering discipline of designing protocols, applications, services, and infrastructure so cryptographic mechanisms can be updated repeatedly, safely, and with minimal disruption. In practical terms, that means avoiding hard-coded algorithm choices, understanding where cryptography is used, and building abstraction, configuration, and testing into systems so transitions—such as the move to post-quantum cryptography—do not become expensive, brittle, one-time rewrites.

Note: This post assumes you know how to build a correct cryptographic system, if you do not, you should not, rather you should seek help from cryptographic professionals.

The Need for Crypto-Agility NOW

The industry has known for at least 15 years that crypto-agility is a solid engineering practice, but sadly, few products support it for their own crypto. The looming threat from PQC makes crypto-agility not just a good idea, but an important forcing function – everyone designing and developing applications must move to use crypto-agility to help migrate to PQC and beyond.

The main threat posed by quantum computers is the potential to break asymmetric algorithms like RSA, Elliptic Curve and Diffie-Hellman, these algorithms are used extensively to:

  • Wrap, exchange, or agree-upon symmetric encryption keys that are then used to bulk encrypt data
  • Sign data and code
  • Authenticate principals

We will focus primarily on the first bullet as this is an endemic problem today and it is the core of the Harvest Now, Decrypt Later (HNDL) threat.

What Makes This Post Different

There are many articles about the importance of crypto-agility, but few focus on HOW to achieve crypto-agility, and that is where this article is different, we will focus on real-world designs and coding mechanics.

Step 0 – Don’t Do Your Own Crypto Agility!

Think about the shared responsibility model, if you use Infrastructure as a Service (IaaS) you need to do more work, but you have more control.

If you use Platform as a Service (PaaS) then PaaS pushes more of the responsibility to the provider, rather than you.

The same applies to cryptography.

Where possible, you should offload tasks like signing and encryption to a service or product you trust has a PQC plan to do the crypto work for you. For example, rather than writing your own code to encrypt backups, use a backup service that performs that task (or has plans to do so) and allows you to control the key wrapping keys.

However, if you must use your own crypto, then read on!

Crypto-Agile Designs

Many applications that protect data with encryption do so without regard for the cryptography used. For example, plaintext is passed to encryption code and is then encrypted with a key, or a key derived from some key material, and then the code writes out the ciphertext.

Something like this:

using System.Security.Cryptography; using var aes = Aes.Create(); aes.Key = SHA256.HashData(Encoding.UTF8.GetBytes(args[1])); byte[] ciphertext = aes.EncryptEcb( await File.ReadAllBytesAsync(args[0]), PaddingMode.Zeros); await File.WriteAllBytesAsync(args[0] + ".enc", ciphertext);

This code is problematic on many fronts, including:

  • Encryption algorithm details are hard-coded in the core code path. This makes crypto agility impossible.
  • The crypto is weak:
    • Using Electronic Code Book (ECB) block cipher mode
    • No data authentication
    • Not using an appropriate Key Derivation Function (KDF). 
    • You might also say there is no Initialization Vector (IV) but an IV is not used by ECB.
  • The ciphertext is just a blob of bytes, there is no metadata to indicate how this blob was created and what cryptographic parameters are used.

Hard-coded algorithm assumptions are a strong anti-pattern for crypto-agility and usually make safe migration to newer algorithms harder or more expensive.

To be crypto-agile, a system must support new ciphersuite metadata and store that metadata with the ciphertext; there are several ways to do this.

Crypto-agility in Microsoft Products

To get a better understanding of how to create crypto-agile solutions, let’s look at how Microsoft has addressed this in some products, notably:

  • Microsoft Office
  • SQL Server and Azure SQL DB
  • Azure Blob Storage

There is no single crypto-agility pattern that fits every application’s needs for agility, but these should give you some ideas.

Microsoft Office

In its Open Office XML (OOXML) file structure, Microsoft Office embeds every aspect of the crypto used to protect a document as metadata in the XML payload. Microsoft Office refers to this structure as Agile Encryption. OOXML is primarily a symmetric key solution, so that is all we will cover here.

I have some C# code that dumps the main crypto metadata from an encrypted OOXML file, you can find it here and the output looks a little like this:

Key Data: saltSize : 16 blockSize : 16 keyBits : 256 hashSize : 64 cipherAlgorithm : AES cipherChaining : ChainingModeCBC hashAlgorithm : SHA512 saltValue (or IV) : ktwu3iMe57cJ0LTDJHwf7g== Password Encryptor: spinCount : 100000 saltSize : 16 blockSize : 16 keyBits : 256 hashSize : 64 cipherAlgorithm : AES cipherChaining : ChainingModeCBC hashAlgorithm : SHA512 saltValue (or IV) : p8MRLOBj/a5MOYG1tvfA/Q== encryptedVerifierHashInput : D8jQbWvjyPK8uWa1Z/0hiw== encryptedVerifierHashValue : ikHKt4eXn<snip>QsfCKVqQaawWe1celUw== encryptedKeyValue : p0lVCnKVd<snip>KrmggpYbeH69p8MBvahw=

This is enough data to create the various cryptographic objects needed to decrypt this document.

Depending on the language and crypto libraries you use, you could use code like this pseudo code to decrypt data given a block of crypto-metadata:

descriptor = parse(encryption_metadata) cipherName = descriptor.cipherAlgorithm chainMode = descriptor.cipherChaining paddingMode = descriptor.padding keyBits = descriptor.keyBits blockSize = descriptor.blockSize hashName = descriptor.hashAlgorithm hashSize = descriptor.hashSize spinCount = descriptor.spinCount IV = decodeBase64(descriptor.saltValue) cipher = GetAlgFromAlgName(cipherName) hash = GetAlgFromAlgName(hashName) ) if cipher is null: fail("unsupported cipher") if hash is null: fail("unsupported hash") cipher.build(keyBits, chainMode, blockSize, paddingMode) plaintext = cipher.decrypt(ciphertext, IV, key) function GetAlgFromAlgName (name): switch name: case "AES": return new Aes() case "TripleDES": return new TripleDes() case "SHA256": return new Sha256() case "SHA384": return new Sha384() case "SHA512": return new Sha512() default: return null

This pattern works well for documents because even though the metadata is large, it’s probably smaller than the document. But it does not work so well with rows of data, such as database platforms.

So, let’s look at that.

SQL Server and Azure SQL DB

SQL Server and Azure SQL DB offer a feature called Always Encrypted (AE) that also supports crypto agility, but rather than store metadata, it has a version number at the start of the ciphertext that maps to set of cryptographic primitives.

Currently, SQL Server only has one version of AE, version 1, but if the SQL team added a new set of cryptographic primitives, then the version number would be bumped to 2.

You can see this version number if you dump the hex-encoded ciphertext, below is an example.

 

 

Look at the first byte of each NationalIDNumber, it’s always 0x01, that’s the version number, and that maps the following ciphersuite:

AEAD_AES_256_CBC_HMAC_SHA_256

Which, when translated to English means:

  • AEAD — Authenticated Encryption with Associated Data: Provides both encryption (confidentiality) + authentication (integrity + authenticity) in one step. It can also protect "associated data" (e.g., metadata) that isn't encrypted.
  • AES_256 — Advanced Encryption Standard with a 256-bit key (strong symmetric encryption).
  • CBC — Cipher Block Chaining mode (handles padding and chaining blocks; requires an Initialization Vector/IV).
  • HMAC_SHA_256 — Hash-based Message Authentication Code (MAC) using SHA-256 (provides the authentication tag/MAC).

This is an Encrypt-then-MAC construction: encrypt the data first, then compute a MAC over the ciphertext (plus associated plaintext data) to authenticate it.

If you look at the .NET SqlClient driver source code, you can see the version number is held in the AlgorithmVersion member variable, and the ciphersuite details are gated on that version number. When a new version is introduced, the code is updated to support it while continuing to read version 1 data and writing new data with the latest version, such as version 2.

Azure Blob Storage Client-side Encryption

The Azure Blob Storage client library for .NET supports encrypting data within client applications before uploading to Azure Storage, and decrypting data while downloading to the client. The library also supports integration with Azure Key Vault for key management.

At the time of writing this, there are two ciphersuite versions supported by the client library. Version 2 came into being because of a Padding Oracle vulnerability (read more here) in v1, rendering v1 obsolete.

Blob Storage client-side encryption supports various key wrapping mechanisms, you can learn more here.

You can see how this code is managed in a crypto-agile manner by looking at the Azure SDK source code.

Post Quantum Crypto and Version Numbering

Imagine over the years, you started with a version 1 ciphersuite, then in 2020 you added a newer version 2, and finally, today with Q-Day around the corner, you want to add a version 3 that is quantum safe.  

This is the pattern you might use using version numbers:

public enum CryptoVersion : byte { V1 = 1, V2 = 2, V3 = 3, Latest = V3, } public static byte[] Encrypt( ReadOnlySpan<byte> plaintext, ReadOnlySpan<char> password, CryptoVersion version = CryptoVersion.Latest) { switch (version) { case CryptoVersion.V1: return EncryptV1(plaintext, password); case CryptoVersion.V2: case CryptoVersion.V3: return EncryptGcm(plaintext, password, version); default: throw new ArgumentOutOfRangeException( nameof(version), version, "Unknown crypto version."); } } public static byte[] Decrypt(ReadOnlySpan<byte> blob, ReadOnlySpan<char> password) { CryptoBlobHeader header = ParseHeader(blob); return header.Version switch { CryptoVersion.V1 => DecryptV1(blob, password, header), CryptoVersion.V2 => DecryptGcm(blob, password, header), CryptoVersion.V3 => DecryptGcm(blob, password, header), _ => throw new CryptographicException( $"Unsupported blob version {(byte)header.Version}."), }; }

This code is simple; when encrypting you pass in (or generate) appropriate cryptographic parameters and then an Encrypt method that then passes it off the correct encryption handler that varies by ciphersuite.

For decrypt, the only parameter you need is the password to derive the key encryption key (KEK) that decrypts the embedded wrapped data encryption key (DEK) and the rest is read from the header metadata that is written as part of the encryption operation.

Over time, if you add more ciphersuite versions, you just bump up the version number and call the Encrypt or Decrypt handler function. Easy! I have a version of this here.

In a future installment, I will add a v4 that also digitally signs the ciphertext blob using ML-DSA, but for the moment, V3 is quantum-safe because it uses quantum-safe symmetric algorithms and key sizes.

I have left out setting the block size, key size, IV, nonce, padding mode, block cipher mode and so on, to keep the code smaller. Store all IVs, salts, and nonces alongside the ciphertext as metadata, and ensure their integrity and authenticity by including them as associated data in an AEAD (Authenticated Encryption with Associated Data) scheme. They are not encrypted, but because they are authenticated by the AEAD construction, any tampering is detected

When your code reads encrypted data, it reads the version number and decrypts the data using the correct set of algorithms and configuration. When your code writes ciphertext it always uses the latest supported version. So, you could read a v1 blob, edit the data and then upon write, use v3 algorithms and settings.

The ciphertext blob has a 4-byte ‘magic’ header, in this case ‘CA42’ for Crypto Agility 42. The ‘42’ is there for no specific reason. Your ‘magic’ header, if you decide to use one, is totally up to you!

The ciphertext blob looks like this on disk across the various example versions:

 

 

Versions 2 and 3 are functionally identical; the only difference is the AES key size, visible in the wrapped DEK blocks; v3 increases the symmetric key from 128-bit to 256-bit, raising the effective security margin against Grover’s algorithm.

Sample code can be found here.

JOSE and Crypto Agility

Another option, especially for greenfield solutions, is to use JOSE.

JOSE (JSON Object Signing and Encryption) provides a strong foundation for crypto agility through its explicit separation of key wrapping (alg) and content encryption (enc) algorithm identifiers in the JWE protected header.

Because algorithm selection is declarative and self-describing, migrating between cipher suites requires no structural changes to the payload format, only a header update and corresponding key material rotation.

This makes JOSE well suited to versioned algorithm tiers, where each version maps cleanly to a distinct alg/enc pairing and older versions can be deprecated without breaking the envelope format.

Looking ahead, the IETF JOSE working group is actively developing algorithm registrations for post-quantum primitives - particularly ML-KEM for key encapsulation and ML-DSA for signatures - meaning the same JWE envelope structure will carry forward into a post-quantum world once those identifiers are standardized, with no changes required to parsing or storage infrastructure. Until then, implementations targeting PQC can use private x-prefixed header parameters as a forward-compatibility shim, accepting the loss of interoperability as a temporary trade-off.

Here's a highly abridged JOSE serialization example using the x- shim for ML-KEM and ML-DSA:

{ // Key wrapping: // ML-KEM-1024 (via x- private header) + HKDF-SHA-512 → AES-256-KW // Content encryption: AES-256-GCM // Signing: ML-DSA-87 (JWS wrapper — see outer envelope) "protected": { // Standard JOSE fields "enc": "A256GCM", // content encryption algorithm "alg": "A256KW", // key wrapping algorithm (KEK → DEK) "kid": "key-2024-v3", // key identifier "cty": "application/json", // content type // PQC shim — private parameters (x- prefix = non-registered, bespoke) "x-kem-alg": "ML-KEM-1024", // FIPS 203; encapsulate the KEK "x-kem-kid": "mlkem-pub-001", // recipient ML-KEM public key id "x-kdf": "HKDF-SHA-512", // derives AES-256-KW KEK from ML-KEM shared secret "x-kdf-info": "v3-kek-derive", // HKDF info string (context binding) "x-sig-alg": "ML-DSA-87", // FIPS 204; signs outer JWS envelope }

CMS and Crypto Agility

CMS is especially relevant for PQC migration because ML-KEM use in CMS is now standardized using _KEMRecipientInfo_, allowing post-quantum key establishment to be incorporated without changing the overall CMS envelope grammar. You can read more here.

CMS and JOSE solve similar problems, but they use different serialization models. CMS is defined with ASN.1 and is usually encoded as a compact binary structure (commonly DER, though BER is also used in some contexts), much like X.509-related formats. JOSE, by contrast, uses JSON-based serializations, often with base64url-encoded components in JWS/JWE, which usually makes it easier for developers to inspect and debug but can increase message size relative to a compact binary encoding.

DER (Distinguished Encoding Rules) and BER (Basic Encoding Rules) are simply encoding rules, DER is stricter than BER.

The Fly in the Ointment – Existing code

So far, we have spoken about creating new systems that use crypto agility. But what about systems we already have in place that simply create a blob of ciphertext data and nothing to describe its crypto settings?

You really have two options.

The first is to use one of the patterns above to wrap the ciphertext blob and call that version 1 or describe all the parameters

The second is to add a distinct header at the start of new ciphertext and include the metadata, and for old data (let’s call it v1) if that header is missing, then it’s old ciphertext with no metadata.

Think of the header as a magic number like that used in a JPEG (0xFF 0xD8 0xFF), GIF89a (GIF89a), PNG (0x89 PNG\r\n\1x1a\n) or PDF (%PDF-) file. You could use something like 0x00 0xC1 PH 3R 0x01, which is a null followed by ‘CIPHER’ and then the version number, 0x01. Of course, there is a small, but non-zero chance that some ciphertext could include this series of magic values, so make sure you code gracefully fails when it does not decrypt legacy data.

Summary

To be honest, this post is about 8 pages longer than I wanted, but I would rather err on the side of completeness. Besides, as JRR Tolkien said of The Lord of the Rings, “This tale grew in the telling.”

Crypto-agility is the engineering capability to change cryptographic primitives safely and repeatedly without redesigning systems, and it is now essential for post-quantum migration.

Crypto-agility requires either self-describing cryptographic metadata or versioned ciphertext formats so implementations can read legacy data while writing with the newest approved algorithms. A well-designed crypto-agile system should aim to read older ciphertext formats long enough to support migration, while writing new data with the newest approved configuration.

Practical patterns range from Office-style embedded metadata, to SQL-style and Azure Blob Storage version numbers, to JOSE/CMS headers and metadata that separate key wrapping from content encryption.

The design rule is simple: remove hard-coded algorithm assumptions, persist enough information to reconstruct the cryptographic context, and build systems so algorithm upgrades become routine engineering rather than emergency rewrites.

Thanks

I would like to thank the following people for their valuable input and review of this post:

  • Jack Richins – Azure Security, PQC
  • Jessica Krynitsky – Windows Security
  • Andrei Popov – Windows Security
  • Pieter Vanhove – Azure Data
  • Jeremy Barton – .NET Crypto
  • Raul Garcia – Microsoft Crypto Board
Read the whole story
alvinashcraft
24 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

Mistral Document AI (with OCR 4) and Mistral Medium 3.5 arrive in Microsoft Foundry

1 Share

In production AI systems, different problems require different model capabilities. Document ingestion, reasoning, coding, and automation workflows rarely rely on a single model. They depend on selecting the right tool for each layer of the stack. 

Microsoft Foundry continues to onboard Mistral models to address these complementary needs. 

This week introduces two additions:  

  • Mistral Document AI (with OCR 4), arriving today: brings structured document understanding into production pipelines 
  • Mistral Medium 3.5, arriving tomorrow: adds an open-weight general-purpose model for reasoning, coding, and agentic workloads 

Together, these releases broaden the range of capabilities available in Foundry, giving developers more flexibility to build, combine, and deploy models across different AI workloads, from document processing to customizable, large-scale AI systems. 

Build more reliable document pipelines with OCR 4 

In production systems, OCR is rarely the end goal. It’s the first step in a larger pipeline. 

Developers building RAG systems, agent workflows, or document automation often spend more time reconstructing layout and structure than on the downstream AI logic itself. Flattened text outputs make it difficult to: 

  • Preserve relationships between elements (tables, headers, sections) 
  • Trace outputs back to source locations for validation or citations 
  • Build reliable ingestion pipelines for large-scale document sets 

Mistral Document AI with OCR 4 directly targets this gap. 

It introduces structure-aware document processing, where outputs are not just text but structured representations of the document, including layout, classification, and spatial context. 

Documents remain one of the largest untapped sources of enterprise intelligence. With Mistral Document AI and OCR 4 available in Microsoft Foundry, organizations can move beyond text extraction and unlock structured, actionable data that powers automation, compliance, and AI-driven decision making at scale.” 
— Marjorie Janiewicz, Chief Revenue Officer, Mistral AI 

What changes with Mistral Document AI (with OCR 4)

OCR 4 enables a different approach to document pipelines: 

  • True structured document understanding 

Introduces paragraph-level bounding boxes and block classification, preserving layout and enabling downstream use cases like citations, validation, and form extraction. 

  • Quality and reliability improvements 

According to Mistral, OCR 4 delivers higher quality outputs with better handling of complex formats and formatting edge cases, compared to its predecessor. 

  • Multilingual at global scale 

Expands to 170 languages, supporting mixed-language documents and global workflows 

  • Supports enterprise workflows and compliance 

Enables structured outputs, traceability, redaction workflows, and human-in-the-loop validation  

  • Efficient at scale 

Optimized for high-throughput, batch document processing, and deployable in a single container, OCR 4 enables cost efficiency and scalability in enterprise environments. 

Where developers are already applying it 

OCR 4 serves as a foundational layer for Document AI, enabling developers to build a range of production-ready workflows. It supports RAG pipelines by generating structured, citation-ready document chunks, powers agentic workflows where systems act on document elements (such as extracting fields or validating signatures), and enables large-scale enterprise ingestion pipelines for search, knowledge bases, and analytics. In regulated scenarios, it also strengthens compliance and audit workflows by providing structured, traceable outputs that support validation and human-in-the-loop review. When deployed in Microsoft Foundry, these capabilities integrate directly into broader AI systems, allowing document understanding to flow into downstream applications without requiring extensive pipeline rework. 

Read Mistral’s blog for more information. 

Mistral Document AI with OCR 4 Pricing and deployment 

Deployment Type 

Pricing 1K/Pages 

(OCR only) 

Pricing 1K/Pages 

(OCR with Annotations) 

Global Standard (all regions) 

$4 

$5 

Data zone standard (US and EU) 

$4.4

$5.5

Mistral Medium 3.5: open-weight reasoning and agentic AI 

Mistral Medium 3.5 expands the Foundry model catalog with a general-purpose model optimized for reasoning, coding, and agent workflows. 

Medium 3.5 is a 128B parameter dense model with a 256K token context window, supporting both text and image inputs. It is also Mistral’s first fully merged flagship model, combining instruction-following, reasoning, and coding capabilities into a single system, reducing the need to orchestrate multiple specialized models.  

What differentiates Medium 3.5 is its open-weight design. Available under a modified MIT license, it gives organizations more cost-efficiency and ability to customize to suit specific needs. The customization is especially compelling for governments, financial services, healthcare, and global enterprises that require strict data residency, compliance, and auditability without giving up advanced AI capabilities.  

Read Mistral Medium 3.5 blog to learn more. 

Mistral Medium 3.5 Pricing and deployment 

Deployment Type 

Input/1M Tokens    

Output/1M Tokens    

Global Standard (all regions)  

 $1.5 

$7.5 

Data zone standard (US and EU)

$1.65

$8.25

Why use Document AI (with OCR 4) and Medium 3.5 on Microsoft Foundry 

These models can be powerful when used together in a single AI architecture. 

Developers can: 

  • Use OCR 4 to convert documents into structured, pipeline-ready data 
  • Use Medium 3.5 to support reason over that data, powering copilots, agents, and automation 

All within Microsoft Foundry’s unified platform. 

"The launch of Mistral Medium 3.5 and OCR 4 in Microsoft Foundry reflects our shared commitment with Microsoft to deliver powerful, enterprise-ready AI. Customers can now access leading AI capabilities through a trusted platform they already use today."

— Dion Ubert, Head of Microsoft Partnership at Mistral AI

Foundry provides the foundation to run these workloads at enterprise scale and within regulated environments. Teams can process large document volumes with OCR 4 while leveraging models like Mistral Medium 3.5 for downstream reasoning and automation, both within a platform that enforces governance, security, and deployment control. With support for flexible deployment methods, organizations can meet strict data residency, auditability, and compliance requirements while scaling AI systems confidently across production workloads. 

Get started today 

Getting started with Mistral on Microsoft Foundry is straightforward: 

  1. Create or access your Microsoft Foundry workspace 
  2. Browse the model catalog and select: mistral-ocr-4-0 for document workflows; Mistral Medium 3.5 for reasoning and agentic workloads
  3. Deploy the model using real-time endpoints or serverless API. Check out Foundry documentation here.
  4. Integrate into your applications: from document pipelines to copilots and automation systems 

With OCR 4 unlocking structured document intelligence and Medium 3.5 enabling efficient, flexible deployment, organizations can start building end-to-end, product-ready AI solutions. 

Read the whole story
alvinashcraft
41 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

.NET July 2026!

1 Share

Once again, it’s time for another .NET July in the Microsoft Zero To Hero community! 🚀
Summer is here, and what better way to make it more exciting than by learning from amazing speakers and exploring hot topics from the world of .NET?
Get ready for a month full of energy, inspiration, and practical knowledge. Whether you are just starting your journey or already building with .NET, this is a great opportunity to fill your learning backpack with new ideas, real-world insights, and fresh motivation. 😎 🪭
Join us for another .NET July, where our fantastic speakers will share their experience, knowledge, and passion with the community.
Register for the sessions, bring your curiosity, and let’s learn together, the Microsoft Learn way. 💙

📢 Gerald Versluis
📅 4th July - 18:00 CETS
📖 Building an AI-Powered Personal Companion App with .NET MAUI
🖇️ Register here

📢 Rodney Littles, II
📅 11th July - 18:00 CEST
📖 C# Abstractions, the lies they tell us, and the fact your likely still doing it wrong
Register here


📢 Shaun Lawrence
📅 17th July - 18:00 CEST
📖 Building accessible applications in .NET MAUI
🖇️ Register here

📢 Mo Pazooki
📅 25th July - 18:00 CEST
📖 Integrating Microsoft Entra ID with .NET Aspire
🖇️ Register here

📢 Einar Ingebrigtsen
📅 31st July - 18:00 CEST
📖 Event Sourcing - AIs best friend
🖇️ Register here




Read the whole story
alvinashcraft
58 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

Only 8.5% of MCP Servers Use OAuth — Here's How to Host One Securely on App Service

1 Share

The Model Context Protocol exploded onto the scene because it's easy. Stand up a server, expose a few tools, point Claude or VS Code at it, and your agent can suddenly read files, hit APIs, and run code. That same ease is the problem: most MCP servers ship with no authentication at all, and they're getting pushed straight to the internet.

The numbers are bleak-into-an-incident-report bad. Astrix Research's State of MCP Server Security 2025 found that only 8.5% of MCP servers use OAuth — the rest lean on static API keys or nothing. And the CVEs have already started:

  • CVE-2025-6514 — a CVSS 9.6 OS command-injection flaw in mcp-remote. If a client connects to a malicious or hijacked MCP server, the server can inject shell commands through the OAuth authorization_endpoint during discovery and achieve remote code execution on the client. Roughly half a million downloads were exposed.
  • CVE-2025-49596 — RCE in the MCP Inspector dev tool, which shipped with no authentication on its local web UI. A crafted request from a webpage you happened to visit could execute code on your machine.

The throughline: MCP doesn't enforce security at the protocol level. The spec is explicit that authorization is optional and implementation-dependent. That's a reasonable design choice for a transport, but it means you own the perimeter. Skip it, and you've published an unauthenticated RPC endpoint that can read secrets and run tools.

So let's not skip it. This post walks through a hardened MCP server on Azure App Service that closes every gap above — and most of it is platform configuration, not code you have to write and get right yourself.

Sample: seligj95/app-service-secure-mcp. One azd up (plus an Entra app registration the hook creates for you) gives you an MCP server behind Easy Auth, talking to Key Vault over a managed identity, with no public network access, fronted by API Management, and an Application Insights alert watching for abuse.

The threat model for a hosted MCP server

Before the architecture, be honest about the attack surface. When an MCP server is internet-reachable, the bad days look like this:

  • Unauthenticated tool invocation. Anyone who finds the endpoint calls your tools. If one of them reads a database or a secret, that's the whole game.
  • Credential exfiltration. A tool that returns a secret value — even "helpfully," for debugging — hands credentials to whatever is driving the session.
  • Prompt injection via tool responses. A compromised or malicious tool return can carry instructions that hijack the calling agent.
  • Path traversal / injection. A tool that concatenates user input into a file path or shell command is the same class of bug we've fought for 25 years, now with an LLM cheerfully supplying the payload.
  • Lateral movement. A server running with a broad identity or a network line of sight to everything becomes a pivot point.

The architecture below maps a defense to each one. None of it is exotic — it's the App Service security stack, pointed at MCP.

The architecture

 
 

Five layers, each one a checkbox or a few lines of Bicep. Let's take them in order.

1. Easy Auth — spec-compliant OAuth you don't have to write

The single most important fix is also the easiest: turn on App Service built-in authentication (Easy Auth) and point it at Entra ID. Now App Service validates the token and rejects unauthenticated requests at the platform, before a single line of your Python runs.

App Service Authentication also has a built-in MCP server authorization mode (Preview) that makes your server comply with the MCP authorization spec: it serves Protected Resource Metadata (PRM) so a compliant MCP client can discover the authorization server and complete the OAuth handshake itself — instead of just getting a bare 401.

In the sample that's an authsettingsV2 resource:

resource authSettings 'Microsoft.Web/sites/config@2024-04-01' = {
  parent: web
  name: 'authsettingsV2'
  properties: {
    globalValidation: {
      requireAuthentication: true
      unauthenticatedClientAction: 'Return401'   // reject, don't redirect
    }
    identityProviders: {
      azureActiveDirectory: {
        enabled: true
        registration: {
          clientId: authClientId
          openIdIssuer: '${environment().authentication.loginEndpoint}${authTenantId}/v2.0'
        }
        validation: {
          allowedAudiences: [ 'api://${authClientId}' ]
        }
      }
    }
  }
}

The piece that makes it MCP-compliant — not just "returns 401" — is enabling PRM. That's one app setting that publishes the metadata document MCP clients look for:

{
  name: 'WEBSITE_AUTH_PRM_DEFAULT_WITH_SCOPES'
  value: 'api://${authClientId}/user_impersonation'
}

unauthenticatedClientAction: 'Return401' gives a clean 401 instead of a login redirect, and PRM turns that 401 into a discoverable OAuth challenge — the client follows the metadata, signs the user in, and retries with a valid token. Recall that 8.5% figure: this is the spec-compliant OAuth the other 91.5% are missing, and you got it from configuration, not code.

One gotcha worth calling out: when App Service creates the Entra registration for you, the default policy only accepts tokens the app itself obtained. For a real MCP client to connect, add its client id to the allowed-applications policy and preauthorize it on the app registration. (Entra has no Dynamic Client Registration, so the client ships a known client id; for VS Code / GitHub Copilot, preauthorization avoids a consent prompt the client won't surface.)

The bonus is that the validated identity is handed to your code. App Service injects the caller's claims into every forwarded request as the X-MS-CLIENT-PRINCIPAL headers — and crucially, it strips any client-supplied copy first, so they can't be forged. The whoami tool just reads them:

def _client_principal(request: Request) -> Dict[str, Any]:
    raw = request.headers.get("x-ms-client-principal")
    # base64-encoded JSON of the caller's claims, injected by Easy Auth
    ...
    return {"authenticated": bool(raw), "name": name, ...}

Your tools now know who's calling without you owning any of the token machinery.

2. Managed identity — stop storing the keys to the kingdom

The static-API-key habit is how secrets leak. Replace it with a system-assigned managed identity: App Service gets an Entra identity that Azure manages, and your code authenticates to Key Vault, Storage, or Azure OpenAI with no stored credential.

This matters for a subtle reason the MCP authorization guidance calls out explicitly: the token a client presents represents access to your server, not to Key Vault. Never forward it downstream — use the managed identity (or an on-behalf-of token) for that hop. Pass-through is a vulnerability; delegation is the fix, and the managed identity is how you delegate without holding a secret.

resource web 'Microsoft.Web/sites@2024-04-01' = {
  identity: { type: 'SystemAssigned' }
  ...
}

In Python, DefaultAzureCredential resolves to that identity automatically — the same code runs locally against your az login and in Azure against the MI:

from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient

credential = DefaultAzureCredential()
client = SecretClient(vault_url=KEY_VAULT_URI, credential=credential)

And least privilege is one role assignment. The sample grants the identity exactly Key Vault Secrets User — read secret values, nothing else:

var keyVaultSecretsUserRoleId = '4633458b-17de-408a-b874-0445c86b69e6'
resource appSecretsUser 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(keyVault.id, appPrincipalId, keyVaultSecretsUserRoleId)
  scope: keyVault
  properties: {
    roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', keyVaultSecretsUserRoleId)
    principalId: appPrincipalId
    principalType: 'ServicePrincipal'
  }
}

There is now no secret used to read secrets. That's the chain of custody you want.

3. Key Vault references — and a tool that won't leak them

Two pieces here. First, Key Vault references keep secrets out of your configuration. You point an app setting at a vault URI, and App Service resolves the value at runtime via the managed identity:

{
  name: 'SECURE_CONFIG_VALUE'
  value: '@Microsoft.KeyVault(SecretUri=${secureConfigSecretUri})'
}

The plaintext never appears in your repo, your Bicep, or the portal's app settings blade — it shows up as a resolved reference.

Second, and this is the part developers get wrong: a tool that reads a secret should never return the secret. The sample's read_secret_metadata proves the managed-identity path works end to end, then deliberately withholds the value:

async def tool_read_secret_metadata(secret_name: str = "demo-secret"):
    secret = client.get_secret(secret_name)
    return {
        "available": True,
        "version": secret.properties.version,
        "value_length": len(secret.value),   # length, never the value
        "note": "Value intentionally withheld — metadata only.",
    }

If your MCP server has a get_secret tool that returns the secret, you've built a credential-exfiltration API with a friendly name. Return metadata; act on the value server-side.

The same discipline applies to input. The safe_lookup tool matches against a fixed allow-list and refuses anything that smells like traversal or injection — it never touches a filesystem or a shell:

suspicious = any(t in key for t in ("..", "/", "\\", ";", "|", "$(", "`"))
if key in DOCS:
    return {"topic": key, "doc": DOCS[key], "found": True}
return {"found": False, "rejected_as_suspicious": suspicious, ...}

safe_lookup("../../etc/passwd") comes back rejected_as_suspicious: true. That is the entire fix for a whole class of CVEs.

4. Private endpoints + APIM — take the server off the internet

Authentication is necessary but not sufficient. The strongest version of "don't expose your MCP server" is to not expose it — give the App Service and Key Vault private endpoints, disable public network access, and let API Management be the only public door.

resource web 'Microsoft.Web/sites@2024-04-01' = {
  properties: {
    virtualNetworkSubnetId: appSubnetId     // outbound: reach KV's private endpoint
    publicNetworkAccess: 'Disabled'         // inbound: no public access at all
    ...
  }
}

Now the App Service hostname returns nothing from the internet. The only ingress is the APIM gateway, which runs the security policy before traffic ever reaches the VNet — validate the Entra JWT, rate-limit per caller, and (the documented extension point) run a content-safety check:

<inbound>
  <base />
  <validate-jwt header-name="Authorization" failed-validation-httpcode="401">
    <openid-config url="https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration" />
    <required-claims>
      <claim name="aud"><value>api://{clientId}</value></claim>
    </required-claims>
  </validate-jwt>
  <rate-limit-by-key calls="60" renewal-period="60"
                     counter-key="@(context.Request.IpAddress)" />
  <set-backend-service backend-id="mcp-backend" />
</inbound>

This is defense in depth: APIM validates the token, and Easy Auth validates it again at the app. An attacker has to get past a public gateway with JWT enforcement and rate limiting just to reach a private endpoint that also demands a valid token. Compare that to the median MCP server, which is a raw port on the internet.

The honest trade-off: this is a security reference architecture, not a 60-second demo. APIM takes ~30–45 minutes to provision, and because the app is private, you test through the gateway, not the App Service hostname. That friction is the point — it's the same friction an attacker hits.

5. Monitoring — see the abuse before it's an incident

The last layer is visibility. The Azure Monitor OpenTelemetry distro auto-instruments FastAPI, and the audit_event tool emits a structured custom event per call. A scheduled-query alert watches the rate of those events and fires when tool invocations spike — the signature of an agent looping over a sensitive tool, or someone probing the surface:

criteria: {
  allOf: [{
    query: 'customEvents | where name == "mcp_tool_audit" | summarize calls = count() by bin(timestamp, 5m)'
    metricMeasureColumn: 'calls'
    operator: 'GreaterThan'
    threshold: 100
  }]
}

Tune the threshold to your baseline. The point is that "is someone hammering my credential-reading tool?" becomes an alert, not a forensic exercise after the fact.

Deploy it

azd auth login
azd up

A preprovision hook creates the Entra ID app registration and stashes its client id in the azd environment, so Easy Auth and the APIM policy wire themselves up. Then Bicep provisions the VNet, private endpoints, Key Vault, App Service, APIM, and the monitoring stack. (Grab a coffee for the APIM step.)

To verify, get a token and call through the gateway:

TOKEN=$(az account get-access-token \
  --resource "api://$(azd env get-value AZURE_AUTH_CLIENT_ID)" \
  --query accessToken -o tsv)

curl -s -X POST "$(azd env get-value APIM_MCP_URL)" \
  -H "Authorization: Bearer $TOKEN" -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"whoami","arguments":{}}}'

The response shows the authenticated principal. Drop the token and you get a 401 from APIM — exactly what you want an unauthenticated caller to see.

To let a real MCP client (VS Code, Claude) sign users in itself rather than pasting a bearer token, point it at the same URL: PRM is already published, so the client discovers the auth server and runs the OAuth flow. Just make sure its app id is allowed — azd env set AZURE_MCP_CLIENT_APP_ID <client-id> before azd up adds it to the allowed-applications policy — and preauthorize it on the server's app registration so clients that don't surface a consent prompt can connect.

Once it's deployed and you've verified it, take the App Service off the public internet with a one-line flip — azd env set LOCK_DOWN_WEB_APP true && azd provision. (The first deploy keeps public access on just long enough to push the code, because a fully-private app can only be deployed from inside its VNet. The sample's README walks through both phases.)

Why this matters

MCP is going to be the USB-C of agent tooling, and right now most of the connectors are unauthenticated and exposed. The CVEs aren't hypothetical — they have numbers and CVSS scores. But the fix isn't a research project. On App Service, the perimeter is mostly configuration: flip on Easy Auth, use a managed identity, reference Key Vault, go private, front it with APIM, and alert on the logs.

That's the difference between "I shipped an MCP server" and "I shipped an MCP server I'd put in production." If you're hosting MCP — especially anywhere a compliance auditor will eventually look — start from the secure shape, not the demo shape.

Try it

Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories