Skip to content

Add optional Minimal API security defaults - #836

Merged
AndreaCuneo merged 11 commits into
masterfrom
copilot/docsmediator-frameworkprogressaspnetcore-hosting-g
Aug 4, 2026
Merged

Add optional Minimal API security defaults#836
AndreaCuneo merged 11 commits into
masterfrom
copilot/docsmediator-frameworkprogressaspnetcore-hosting-g

Conversation

Copilot AI commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

The mediator framework lacked reusable ASP.NET Core Minimal API security-header and HSTS defaults. This task adds an opt-in Ark security profile and applies it to the mediator sample.

  • Security profile
    • Adds default API, Scalar/Swagger, and gRPC reflection policies.
    • Removes the Server header.
    • Enables security headers and HSTS middleware.
  • Sample integration
    • Applies the profile before exception handling and endpoint middleware.
  • Documentation and coverage
    • Documents registration and middleware ordering.
    • Adds TestServer coverage for security headers.
  • Dependency metadata
    • Updates package references and lock files.
services.AddArkMinimalApiSecurity();

app.UseArkMinimalApiSecurity();

Copilot AI and others added 8 commits August 4, 2026 09:11
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
@AndreaCuneo
AndreaCuneo marked this pull request as ready for review August 4, 2026 10:28
@AndreaCuneo
AndreaCuneo requested a review from a team as a code owner August 4, 2026 10:28
Copilot AI lite review requested due to automatic review settings August 4, 2026 10:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds an opt-in Minimal API “security profile” to Ark.Tools.AspNetCore.MinimalApi, wires it into the mediator sample startup sequence, and documents the recommended registration/middleware ordering. Also introduces a TestServer test and updates lockfiles for the new dependency.

Changes:

  • Add AddArkMinimalApiSecurity() / UseArkMinimalApiSecurity() extensions backed by NetEscapades.AspNetCore.SecurityHeaders + HSTS.
  • Apply the new middleware early in the mediator sample pipeline and document the intended ordering.
  • Add a MinimalApi TestServer test and update relevant packages.lock.json files.

Reviewed changes

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

Show a summary per file
File Description
tests/Ark.Tools.AspNetCore.MinimalApi.Tests/packages.lock.json Adds the transitive lock entry for the new security headers dependency in tests.
tests/Ark.Tools.AspNetCore.MinimalApi.Tests/ArkMinimalApiSecurityTests.cs Adds TestServer coverage for security headers (currently missing an HSTS assertion).
src/aspnetcore/Ark.Tools.AspNetCore.MinimalApi/packages.lock.json Locks the new direct dependency for the MinimalApi package.
src/aspnetcore/Ark.Tools.AspNetCore.MinimalApi/ArkMinimalApiSecurityExtensions.cs Introduces the new opt-in security profile extensions (contains a compile issue + policy selector mismatch).
src/aspnetcore/Ark.Tools.AspNetCore.MinimalApi/Ark.Tools.AspNetCore.MinimalApi.csproj Adds NetEscapades.AspNetCore.SecurityHeaders package reference.
samples/Ark.MediatorFramework.Sample/test/Ark.MediatorFramework.Sample.Tests/packages.lock.json Updates sample test lockfile for the new transitive dependency.
samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.WebInterface/SampleStartup.cs Applies the new security profile in the sample service registration and middleware ordering.
samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.WebInterface/packages.lock.json Updates sample web lockfile for the new transitive dependency.
docs/mediator-framework/guide/host-setup-and-composition.md Documents registration and updated middleware ordering including the new security profile.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Andrea Cuneo <kaildio@gmail.com>
Copilot AI review requested due to automatic review settings August 4, 2026 10:40

@AndreaCuneo AndreaCuneo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

also integrate master and ensure build and tests success @copilot

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Suppressed comments (4)

src/aspnetcore/Ark.Tools.AspNetCore.MinimalApi/ArkMinimalApiSecurityExtensions.cs:40

  • The "Swagger" policy is registered but never selected: for /swagger and /openapi paths the selector always returns the "Scalar" policy, so the "Swagger" policy is dead code (and any future divergence between the two policies would silently not apply).
                if (path.StartsWithSegments("/scalar", StringComparison.OrdinalIgnoreCase)
                    || path.StartsWithSegments("/swagger", StringComparison.OrdinalIgnoreCase)
                    || path.StartsWithSegments("/openapi", StringComparison.OrdinalIgnoreCase))
                {
                    return context.ConfiguredPolicies["Scalar"];
                }

src/aspnetcore/Ark.Tools.AspNetCore.MinimalApi/ArkMinimalApiSecurityExtensions.cs:6

  • This file uses HeaderPolicyCollection but doesn't import the NetEscapades.AspNetCore.SecurityHeaders namespace, which makes the type reference unresolved.
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

src/aspnetcore/Ark.Tools.AspNetCore.MinimalApi/ArkMinimalApiSecurityExtensions.cs:45

  • The gRPC reflection selector uses StartsWithSegments("/grpc.reflection"), but reflection endpoints are typically under the first segment "grpc.reflection.v1alpha.ServerReflection". StartsWithSegments requires a segment boundary ('/' or end), so this condition won't match and the reflection policy won't apply.
                if (path.StartsWithSegments("/grpc.reflection", StringComparison.OrdinalIgnoreCase))
                {
                    return context.ConfiguredPolicies["GrpcReflection"];
                }

src/aspnetcore/Ark.Tools.AspNetCore.MinimalApi/ArkMinimalApiSecurityExtensions.cs:38

  • SetPolicySelector introduces path-based branching for Scalar/Swagger/OpenAPI and gRPC reflection responses, but the new tests only verify the default ("/") case. Add coverage for at least one documentation path (e.g. /scalar or /swagger) and a gRPC reflection path to ensure the selector stays correct.
            .SetPolicySelector(context =>
            {
                var path = context.HttpContext.Request.Path;

                if (path.StartsWithSegments("/scalar", StringComparison.OrdinalIgnoreCase)
                    || path.StartsWithSegments("/swagger", StringComparison.OrdinalIgnoreCase)
                    || path.StartsWithSegments("/openapi", StringComparison.OrdinalIgnoreCase))
                {

Copilot AI and others added 2 commits August 4, 2026 10:48
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
…aster

Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 4, 2026 10:55

Copilot AI commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

also integrate master and ensure build and tests success @copilot

Merged master into branch (resolved lock file conflicts by regenerating), full solution builds with 0 warnings/errors. Commit: 5f639fd2.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/aspnetcore/Ark.Tools.AspNetCore.MinimalApi/ArkMinimalApiSecurityExtensions.cs:7

  • HeaderPolicyCollection is used but its namespace isn't imported in this file. Unless it's brought in via a global using, this will not compile; add the NetEscapades using (or fully-qualify the type).
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

namespace Ark.Tools.AspNetCore.MinimalApi;

src/aspnetcore/Ark.Tools.AspNetCore.MinimalApi/ArkMinimalApiSecurityExtensions.cs:39

  • The policy selector routes /swagger and /openapi to the "Scalar" policy, leaving the "Swagger" policy unused. Either remove the unused policy or return the "Swagger" policy for those paths to keep the configuration consistent and future-proof.
                if (path.StartsWithSegments("/scalar", StringComparison.OrdinalIgnoreCase)
                    || path.StartsWithSegments("/swagger", StringComparison.OrdinalIgnoreCase)
                    || path.StartsWithSegments("/openapi", StringComparison.OrdinalIgnoreCase))
                {
                    return context.ConfiguredPolicies["Scalar"];

@AndreaCuneo
AndreaCuneo merged commit 0bff452 into master Aug 4, 2026
7 checks passed
@AndreaCuneo
AndreaCuneo deleted the copilot/docsmediator-frameworkprogressaspnetcore-hosting-g branch August 4, 2026 11:11
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