Reference Architecture
The reference architecture sample demonstrates all major Tayra features working together in a single application. Use it as a starting point for evaluating Tayra or as a template for integrating PII protection into your own projects.
Running the Sample
cd samples/Tayra.Samples.ReferenceArchitecture
dotnet runThe sample runs entirely in-memory with no external dependencies — no database, no message broker, no key vault.
What It Demonstrates
The sample walks through 7 features sequentially, printing results to the console:
1. Field-Level Encryption
Encrypts a Customer entity with all Tayra attribute types:
public class Customer
{
[DataSubjectId(Prefix = "cust-")]
public string Id { get; set; }
[PersonalData]
[BlindIndex(Transforms = ["lowercase", "trim"])]
public string Name { get; set; }
[PersonalData(Masking = MaskingStrategies.MaskEmailDomain)]
[BlindIndex(Transforms = ["lowercase"])]
public string Email { get; set; }
[PersonalData(MaskValue = "***")]
public string SocialSecurityNumber { get; set; }
[DeepPersonalData]
public Address? Address { get; set; }
[SerializedPersonalData]
public DateTime DateOfBirth { get; set; }
public string AccountType { get; set; } // Not PII
}ITayra encrypts all PII fields in one call and decrypts them back for a full round-trip.
2. JSON Serialization with PII Encryption
Uses the Tayra.Json integration to encrypt PII during JsonSerializer.Serialize and decrypt during JsonSerializer.Deserialize:
var jsonOptions = new JsonSerializerOptions { WriteIndented = true };
jsonOptions.UseTayra(fieldEncrypter, metadataCache);
var json = JsonSerializer.Serialize(customer, jsonOptions);
// PII fields are encrypted in the JSON output
var restored = JsonSerializer.Deserialize<Customer>(json, jsonOptions);
// PII fields are decrypted back to plaintext3. Key Rotation
Rotates the encryption key for a data subject and re-encrypts all fields with the new key:
var result = await tayra.RotateKeyAsync("cust-alice-001");
await tayra.ReEncryptAsync(customer);4. Crypto-Shredding (GDPR Art. 17)
Deletes the encryption key for a data subject, making all their PII permanently unreadable:
await tayra.ShredAsync("cust-bob-002");
await tayra.DecryptAsync(bob);
// bob.Name → "" (empty, key destroyed)
// bob.SocialSecurityNumber → "***" (custom replacement)
// bob.AccountType → "Standard" (not PII, unchanged)5. PII Data Map (GDPR Art. 30)
Generates an inventory of all PII fields across all registered entity types:
var report = compliance.GenerateInventory();
// Lists entity types, PII fields, encryption status, blind index coverage
var markdown = compliance.ExportInventoryAsMarkdown();6. Compliance Report Generation
Generates HTML reports for GDPR compliance:
var art30Html = compliance.RenderArticle30Report(report, new Article30Options
{
ControllerName = "Acme Corp",
DpoContact = "dpo@acme.com",
ProcessingPurpose = "Customer account management",
});
var coverageHtml = compliance.RenderCoverageReport(report);
var lifecycleHtml = compliance.RenderKeyLifecycleReport(lifecycleData);7. Breach Notification (GDPR Art. 33/34)
Assesses breach impact and generates notification reports:
var impact = await compliance.AssessBreachAsync(new BreachDetails
{
DiscoveredAt = DateTimeOffset.UtcNow,
Description = "Unauthorized access to customer database backup",
AffectedKeyPrefixes = ["cust-"],
});
var notification = await compliance.GenerateBreachReportAsync(impact);
var breachHtml = compliance.RenderBreachReport(notification);Domain Model
The sample includes two entity types that demonstrate cross-entity PII relationships:
| Entity | PII Fields | Description |
|---|---|---|
Customer | Name, Email, Phone, SSN, Address (nested), DateOfBirth | All Tayra attribute types |
Order | ShippingName, ShippingAddress | PII linked to customer via [DataSubjectId] |
The Address class demonstrates [DeepPersonalData] — a nested object whose PII fields are recursively encrypted when the parent is encrypted.
Service Registration
The reference architecture uses both Tayra.Core and Tayra.Compliance:
using Tayra.Compliance;
services.AddTayra(opts => opts.LicenseKey = licenseKey)
.AddCompliance(complianceOpts =>
{
complianceOpts.ApplicationName = "Tayra Reference Architecture";
complianceOpts.AddEntityType<Customer>();
complianceOpts.AddEntityType<Order>();
complianceOpts.AddEntityProvider<Customer, CustomerEntityProvider>();
complianceOpts.AddEntityProvider<Order, OrderEntityProvider>();
});Expected Output
╔══════════════════════════════════════════════════════════════╗
║ Tayra Reference Architecture Sample ║
║ End-to-End PII Data Protection for .NET ║
╚══════════════════════════════════════════════════════════════╝
── 1. Field-Level Encryption ─────────────────────────────────
Before encryption:
Name: Alice Johnson
Email: alice@example.com
After encryption:
Name: AQz8x...
Email: AQf3k...
After decryption (round-trip):
Name: Alice Johnson
Email: alice@example.com
── 4. Crypto-Shredding (GDPR Art. 17 — Right to Erasure) ────
After crypto-shredding:
Name: "" (empty — key destroyed)
SSN: "***" (custom replacement)
── 5. PII Data Map (GDPR Art. 30) ───────────────────────────
Entity types with PII: 3
Total PII fields: 9
All features demonstrated successfully!Extending the Sample
To add your own integrations:
- EF Core: Replace
InMemoryDataStorewith a realDbContextand addservices.AddTayraEFCore() - MassTransit: Add message types with
[PersonalData]and configureUseTayra()on the bus - Serilog: Add
.Destructure.WithTayra()to the logger configuration - MediatR: Add
services.AddTayraMediatR()for pipeline encryption
See Also
- Getting Started -- Quick start tutorial
- Installation -- All available packages
- PII Data Map -- Art. 30 processing records
- Compliance Reports -- HTML report generation
- CLI Tool -- Operational commands
