The OpenApiFeatureFlags mark: two toggle pills between square brackets, in Solarized cyan

OpenApiFeatureFlags

Feature flags for Swagger and OpenAPI documents.

Mark an endpoint, action, property or parameter with [OpenApiFeatureFlag] and it appears in your generated document only while the flag is enabled. Documentation-only by design: runtime behaviour never changes.

$ dotnet add package OpenApiFeatureFlags.Swashbuckle
MIT licensed .NET 8 · 9 · 10 3 document engines 8 packages, one version 647 tests passing

The document follows the flag, not the code

With NewCheckout off, /api/orders/checkout is not in the document. With it on, it is. No restart, no rebuild, no conditional compilation.

The sample application's Swagger UI with the NewCheckout flag off, then on; the checkout operation appears without a restart

The running sample with the flags off and on.

Get started in one call

Register the library next to your document engine. Only one line changes between engines.

builder.Services.AddOpenApiFeatureFlagsWithFeatureManagement();

builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "1.0" });

    // Register this LAST: it rewrites what the previous filters touched.
    options.AddOpenApiFeatureFlagFilters();
});

Package: OpenApiFeatureFlags.Swashbuckle. Works on every supported .NET version. Also install OpenApiFeatureFlags.FeatureManagement or OpenApiFeatureFlags.OpenFeature, or bring your own flag source.

Mark what is gated

The attribute works on a controller, an action, a model property or a parameter. Two attributes on one target are ANDed.

[OpenApiFeatureFlag("NewCheckout")]                  // gates this operation
[HttpPost("checkout")]
public IActionResult Checkout() => Ok();

public sealed class Order
{
    [OpenApiFeatureFlag("LoyaltyProgram")]           // gates one schema property
    public int LoyaltyPoints { get; set; }
}

Descriptions too: wrap gated prose in <gate flag="X">...</gate> inside the XML comment (escaped form under NSwag). Read the guide.

What you get

The small surface of one attribute, and the guarantees that make it safe to publish.

Three engines, one attribute

Swashbuckle, the built-in Microsoft.AspNetCore.OpenApi and NSwag, with the same semantics everywhere. FastEndpoints runs through the built-in engine.

Three modes

Remove (default), Annotate (adds x-feature-flag to the operation) and Include. One option switches the behaviour.

Flags from where you already keep them

Microsoft.FeatureManagement, the CNCF OpenFeature standard, or your own IFeatureFlagSource. Azure App Configuration works through FeatureManagement.

Fail closed, fail loudly

An unreadable flag hides the element instead of leaking it, and a canary exception fires before a document silently loses released endpoints.

Build-time safety

A companion analyzer package reports the silent traps while you compile: OAFF1001, OAFF2001, OAFF3001, OAFF5001. How they work.

Invisible when unused

With no attribute in the project, the document is byte-identical. Eight packages ship in lockstep at one version, MIT licensed.

Questions the README keeps answering

Short answers to the things people ask before adopting the library.

How do I hide an endpoint from Swagger when a feature flag is off?

Put [OpenApiFeatureFlag("FlagName")] on the controller or the action, register the library next to your document engine, and the operation leaves the generated document while the flag is off. It returns the moment the flag is on, without a restart.

How do I exclude just one property or parameter?

The same attribute goes on the model property or the action parameter. One boundary: under the built-in engine a minimal API's parameter cannot be gated; under NSwag it can, because the delegate is present as a MethodInfo.

Does this change runtime behaviour?

No, and that is a design rule. Hiding an operation from the document leaves the endpoint routeable; hiding a property leaves it serialised. Runtime gating stays in your application code.

How do I gate part of a description sentence?

Wrap the prose in <gate flag="X">...</gate> inside the XML doc comment. Under NSwag write it escaped, because the reader flattens element markup; the analyzers catch a missed escape at build time.

What happens if the flag store cannot be read?

The library fails closed, and it fails loudly: if a document contains gated elements and no flag could be read, it throws FeatureFlagSourceUnavailableException instead of publishing a document that silently lost endpoints. CanaryEnabled = false turns the exception off.

Can it protect an endpoint from being called?

No. Document gating is not access control: hiding an operation leaves the endpoint routeable. Pair it with real authorization.

Which .NET versions and document engines are supported?

The library targets net8.0, net9.0 and net10.0, and supports Swashbuckle, the built-in Microsoft.AspNetCore.OpenApi (net10.0 only) and NSwag. FastEndpoints v8.2 or later is covered by the built-in-engine adapter.

How is this different from writing my own IOperationFilter?

For one static rule, write the filter. This library is for the whole problem: one attribute with the same semantics across three engines, three modes, gating for operations, parameters, schema properties and prose, fail-closed evaluation, a planning layer with logging, and analyzers for the silent authoring mistakes.

Documentation

Guides, references and the reasoning behind the design, all in the repository.

README Full quickstart, modes, guarantees and the FAQ.
Built-in engine guide The net10.0 engine and the minimal-API parameter boundary.
NSwag guide Native processors and the escaped-gate rule in XML comments.
FastEndpoints guide Wiring and its two measured boundaries.
Analyzers The OAFF rules and how to set severities.
Descriptions Gating prose inside descriptions.
Flag sources FeatureManagement, OpenFeature, your own, and async-only stores.
Modes What Remove, Annotate and Include produce.
Security Posture and availability trade-offs.
Troubleshooting Nothing is hidden, or too much is.
Design notes Locked decisions and the measurements behind them.
Samples Four runnable sample applications: Swashbuckle, built-in, NSwag and FastEndpoints.
Changelog What changed, and when.