Build bulletproof FDA-compliant MedTech software with these 5 .NET code patterns. Ensure audit trails, e-signatures & HIPAA security. Download our free checklist.
Build bulletproof FDA-compliant MedTech software with these 5 .NET code patterns. Ensure audit trails, e-signatures & HIPAA security. Download our free checklist.
For CTOs and software architects in MedTech, compliance isn't a feature—it's the foundation. A single audit failure or data breach can cost millions and destroy reputations. Off-the-shelf software often forces compromises, but bespoke .NET development for Manufacturing Industry lets you bake compliance directly into your architecture.
These five .NET code patterns are battle-tested in regulated environments. They will help you build applications that not only meet 21 CFR Part 11, HIPAA, and IEC 62304 standards but are also more secure, scalable, and maintainable.
"Implementing these patterns was a key factor in our successful ISO 13485 audit. The auditors were impressed by the built-in traceability."
— Lead Developer, Diagnostic Device Startup & Facile Technolab Client
The Problem: FDA regulations require a secure, time-stamped audit trail for every creation, modification, or deletion of critical data. Manually logging these actions is error-prone and unsustainable.
The .NET Solution: Use Entity Framework Core's IDbCommandInterceptor` to automatically log every data change without cluttering your business logic.
public class AuditInterceptor : DbCommandInterceptor { public override ValueTask<InterceptionResult<int>> NonQueryExecutingAsync( DbCommand command, CommandEventData eventData, InterceptionResult<int> result, CancellationToken cancellationToken = default) { if (command.CommandText.StartsWith("UPDATE") || command.CommandText.StartsWith("DELETE")) { // Capture: User, Timestamp, Table, Action, Old/New Values _auditService.LogChange(eventData.Context, command); } return base.NonQueryExecutingAsync(command, eventData, result, cancellationToken); } } // Program.cs builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlServer(connectionString) .AddInterceptors(new AuditInterceptor()));
Why it's Bulletproof: Compliance becomes automatic and unavoidable. Every change is logged, creating an immutable record for auditors.
The Problem: You must enforce the "principle of least privilege" to protect electronic protected health information (ePHI). Generic admin/user roles are not enough for HIPAA.
The .NET Solution: Implement fine-grained, policy-based authorization in ASP.NET Core.
// 1. Define Policies (in Program.cs) builder.Services.AddAuthorization(options => { options.AddPolicy("CanViewPHI", policy => policy.RequireClaim("Permission", "ViewPatientData") .RequireRole("Clinician", "Researcher")); options.AddPolicy("CanExportData", policy => policy.RequireClaim("Permission", "ExportData") .RequireRole("SystemAdministrator") .Requirements.Add(new AuditRequirement())); // Custom requirement }); // 2. Use in Controller [Authorize(Policy = "CanViewPHI")] public async Task<IActionResult> GetPatientData(int patientId) { // Your logic here } // 3. Use in Blazor Component <AuthorizeView Policy="CanExportData"> <Authorized> <button @onclick="ExportData">Export Data</button> </Authorized> </AuthorizeView>
Why it's Bulletproof: Access control is centralized, declarative, and easy to audit. You can prove exactly who has access to what.
The Problem: 21 CFR Part 11 requires electronic signatures that are legally binding, which involves linking a signature to a specific record and ensuring it cannot be altered.
The .NET Solution: Create a service that generates a secure hash of the signed data and stores it with the signature.
public class ElectronicSignatureService { public async Task<SignatureResult> SignRecordAsync(string userId, string reason, string recordJson, string privateKey) { // 1. Hash the record payload var recordHash = SHA256.HashData(Encoding.UTF8.GetBytes(recordJson)); // 2. Create signature payload (user + timestamp + reason + record hash) var signaturePayload = $"{userId}|{DateTime.UtcNow}|{reason}|{Convert.ToBase64String(recordHash)}"; // 3. Cryptographically sign the payload using var rsa = RSA.Create(); rsa.ImportFromPem(privateKey); var signature = rsa.SignData(Encoding.UTF8.GetBytes(signaturePayload), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); // 4. Store the signature, payload, and timestamp await _dbContext.Signatures.AddAsync(new Signature { UserId = userId, Timestamp = DateTime.UtcNow, Reason = reason, RecordHash = recordHash, SignatureData = signature }); return new SignatureResult(/* ... */); } // Method to verify a signature public bool VerifySignature(Signature signature) { /* ... */ } }
Why it's Bulletproof: This provides non-repudiation. Any change to the original record invalidates the hash, making tampering evident.
The Problem: Hardcoded connection strings or API keys in app settings are a critical security vulnerability.
The .NET Solution: Leverage Azure Key Vault and the .NET Configuration system for secure secret management.
// Program.cs - Configure Azure Key Vault builder.Configuration.AddAzureKeyVault( new Uri($"https://{builder.Configuration["KeyVaultName"]}.vault.azure.net/"), new DefaultAzureCredential()); // App Settings.json (Only contains non-secret values) { "KeyVaultName": "my-medtech-vault", "DatabaseName": "ProductionDB" } // Controller - Access secrets securely through IConfiguration public class DeviceController : Controller { private readonly string _connectionString; public DeviceController(IConfiguration config) { // Secret is fetched securely from Key Vault at runtime _connectionString = config["DatabaseConnectionString"]; } }
Why it's Bulletproof: Secrets are never stored in code or config files. Access is logged and controlled via Azure Active Directory, providing a clear audit trail.
The Problem: Data must be valid and conform to business rules before it hits your business logic to ensure data integrity (an ALCOA+ principle).
The .NET Solution: Create custom validation attributes for model validation in APIs.
// Custom validation attribute for FDA Unique Device Identification (UDI) public class ValidUDIAttribute : ValidationAttribute { protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var udi = value as string; if (udi != null) { if (!IsValidUDIFormat(udi)) { return new ValidationResult("Invalid UDI format. Must meet FDA GUDID requirements."); } } return ValidationResult.Success; } private bool IsValidUDIFormat(string udi) { /* Validation logic */ } } // Use on Data Transfer Object (DTO) public class CreateDeviceDto { [Required] [ValidUDI] // <-- Custom Attribute public string UDI { get; set; } [Required] [StringLength(100, MinimumLength = 1)] public string DeviceName { get; set; } }
Why it's Bulletproof: Validation is consistent, reusable, and happens automatically at the API boundary, preventing invalid data from ever entering your system and corrupting your records.
Building this level of compliance into your software requires deep expertise in both .NET and regulatory standards. At Facile Technolab, we don't just write code; we build compliance-by-design into the architecture of your application.
Our MedTech Accelerator Framework includes pre-built, audited modules for these very patterns, cutting your development time and technical risk in half.