A token can have a valid signature and still belong to another API. A caller can authenticate successfully and still lack permission to write an order. I want those failures to remain separate, both in the implementation and in the HTTP response.
I built entra-id-api-dotnet , a small ASP.NET Core 8 API demonstrating JWT validation and independent scope and role policies. Its 14 integration cases pass in GitHub Actions CI. They exercise the actual JWT middleware with locally signed tokens; they do not establish a working connection to a live Microsoft Entra tenant.
Here is how I set up that boundary and what the tests actually demonstrate.
Start with one tenant and one audience
The application requires two configuration values: Entra:TenantId and Entra:Audience . Startup rejects an invalid or empty tenant GUID and a blank audience.…