ASP.NET Core
Tayra integrates with ASP.NET Core through response scrubbing middleware that automatically removes or redacts [PersonalData] fields from JSON responses. This prevents personal data from being inadvertently exposed through API endpoints, log aggregators, or downstream consumers that should not have access to raw PII.
Install
dotnet add package Tayra.AspNetCoreInstall-Package Tayra.AspNetCoreSetup
Register Tayra core services, a key store, and the ASP.NET Core scrubbing middleware:
var builder = WebApplication.CreateBuilder(args);
// Register Tayra core services and key store
builder.Services.AddTayra(opts => opts.LicenseKey = licenseKey);
// Register Tayra ASP.NET Core response scrubbing
builder.Services.AddTayraAspNetCore();
var app = builder.Build();
// Add the response scrubbing middleware to the pipeline
app.UseTayraResponseScrubbing();The setup consists of three calls:
AddTayraAspNetCore()registersTayraScrubbingOptionsand related servicesUseTayraResponseScrubbing()adds theTayraResponseScrubbingMiddlewareto the pipeline- Tayra core services (
AddTayra()) and a key store provide the metadata cache used to identify PII fields
Middleware Order
Call UseTayraResponseScrubbing() before any response compression middleware but after routing and authentication. The middleware needs access to endpoint metadata to check for [ScrubPersonalData] attributes.
Options
// TayraScrubbingOptions — controls PII scrubbing behavior
//
// Property Type Default Description
// ────────────── ──────────────── ─────────────────── ─────────────────────────────────────
// GloballyEnabled bool false Scrub all endpoints (not just attributed ones)
// Mode ScrubbingMode Redact Redact or Remove PII fields
// RedactedValue string "[REDACTED]" Replacement text for redacted fields
// ContentTypes HashSet<string> {"application/json"} Content types to scrub
builder.Services.AddTayraAspNetCore(opts =>
{
opts.GloballyEnabled = false; // Only scrub endpoints with [ScrubPersonalData]
opts.Mode = ScrubbingMode.Redact; // Replace PII values with RedactedValue
opts.RedactedValue = "[REDACTED]"; // The replacement string
opts.ContentTypes = ["application/json"]; // Only scrub JSON responses
});| Property | Type | Default | Description |
|---|---|---|---|
GloballyEnabled | bool | false | Scrub all endpoints (not just attributed ones) |
Mode | ScrubbingMode | Redact | Redact replaces PII values; Remove deletes the JSON property entirely |
RedactedValue | string | "[REDACTED]" | The replacement text used in Redact mode |
ContentTypes | HashSet<string> | {"application/json"} | Only responses with matching Content-Type headers are processed |
Scrubbing Modes
ScrubbingMode.Redact-- Replaces PII field values with theRedactedValuestring. The JSON structure is preserved, and consumers can see which fields exist but not their values.ScrubbingMode.Remove-- Removes PII fields entirely from the JSON response. Consumers will not see the fields at all.
The ScrubPersonalData Attribute
Use [ScrubPersonalData] to opt individual endpoints or controllers into response scrubbing:
// The [ScrubPersonalData] attribute marks endpoints for response scrubbing.
// Apply it to controller classes or individual action methods.
//
// [ApiController]
// [Route("api/[controller]")]
// public class CustomersController : ControllerBase
// {
// [HttpGet("{id}")]
// [ScrubPersonalData] // <-- PII fields will be scrubbed from the JSON response
// public async Task<CustomerResponse> Get(string id) { ... }
// }The attribute can be applied to:
- Controller classes -- All actions in the controller are scrubbed
- Action methods -- Only the specific action is scrubbed
- Minimal API delegates -- Applied inline on the lambda
When GloballyEnabled is false (the default), only endpoints decorated with [ScrubPersonalData] are scrubbed. When GloballyEnabled is true, all endpoints are scrubbed regardless of the attribute.
Example Endpoints
// Example using Minimal APIs with the [ScrubPersonalData] attribute.
// PII fields in the response are replaced with "[REDACTED]" by the middleware.
app.MapGet("/api/customers/{id}", [ScrubPersonalData] (string id) =>
{
return new CustomerResponse
{
CustomerId = id,
Name = "Jane Doe",
Email = "jane@example.com",
AccountType = "Premium",
};
});
// Without the attribute, PII fields pass through untouched
app.MapGet("/api/customers/{id}/raw", (string id) =>
{
return new CustomerResponse
{
CustomerId = id,
Name = "Jane Doe",
Email = "jane@example.com",
AccountType = "Premium",
};
});In this example:
GET /api/customers/42returns the response withNameandEmailreplaced by"[REDACTED]"because the endpoint has[ScrubPersonalData]GET /api/customers/42/rawreturns the full response with plaintext PII because it lacks the attribute
Example scrubbed response:
{
"customerId": "42",
"name": "[REDACTED]",
"email": "[REDACTED]",
"accountType": "Premium"
}How Response Scrubbing Works
The TayraResponseScrubbingMiddleware operates in five steps:
- Check eligibility -- Examines the endpoint metadata for
[ScrubPersonalData](or checksGloballyEnabled) - Buffer the response -- Replaces the response body stream with a
MemoryStreamto capture the output - Execute the pipeline -- Calls
next(context)to let the rest of the pipeline write the response - Parse and scrub -- If the
Content-Typematches, parses the JSON response and replaces or removes fields whose names match known[PersonalData]property names - Write the scrubbed response -- Writes the modified JSON back to the original response stream
Field Name Matching
The middleware uses a case-insensitive match against property names registered in the PersonalDataMetadataCache. Any type that has been seen by the Tayra metadata cache (through encryption, decryption, or explicit registration) will have its PII field names recognized for scrubbing.
Use with Encryption
Response scrubbing is complementary to field-level encryption. Encryption protects data at rest in the database, while scrubbing protects data in API responses. You can use both together for defense in depth:
- Store encrypted PII in the database (via EF Core or Marten integration)
- Decrypt on read for authorized endpoints
- Scrub responses for endpoints that should not expose raw PII
See Also
- Getting Started -- End-to-end encryption tutorial
- EF Core Integration -- Database-level encryption
- Marten Integration -- Document database encryption
- Wolverine Integration -- Message pipeline encryption
