EngineeringSolution ArchitectSecurity and Observability

Session 04 - Compliance Frameworks

Tổng Quan Compliance Landscape

Compliance không chỉ là checkbox - nó định hình cách team thiết kế, build và vận hành software. Với .NET trên Azure, nhiều compliance controls đã có sẵn nhưng cần cấu hình đúng.

FrameworkPhạm viAi cần?
SOC 2Security, availability, processing integritySaaS companies, B2B
GDPRData protection cho EU citizensMọi app có EU users
HIPAAHealthcare data protectionHealthcare apps
PCI DSSPayment card dataApps xử lý payment
ISO 27001Information security managementEnterprise, government

SOC 2 - Trust Service Criteria

5 Trust Service Criteria

CriteriaFocus.NET/Azure Implementation
SecurityProtection against unauthorized accessAzure AD, NSG, WAF, encryption
AvailabilitySystem uptime commitmentsSLOs, health checks, DR plan
Processing IntegrityAccurate, complete processingInput validation, idempotency
ConfidentialityData protection for sensitive infoEncryption at rest/transit, Key Vault
PrivacyPII handling per privacy noticeData classification, consent, retention

SOC 2 Technical Controls Mapping

Audit Logging Requirements

csharp
// SOC 2 yêu cầu audit trail cho security events
public class AuditLogEntry
{
    public Guid Id { get; init; } = Guid.NewGuid();
    public DateTimeOffset Timestamp { get; init; } = DateTimeOffset.UtcNow;
    public required string Action { get; init; }       // "User.Login", "Order.Create"
    public required string ActorId { get; init; }       // User ID hoặc Service ID
    public required string ActorType { get; init; }     // "User", "Service", "System"
    public string? ResourceType { get; init; }          // "Order", "User"
    public string? ResourceId { get; init; }
    public string? IpAddress { get; init; }
    public string? UserAgent { get; init; }
    public required string Result { get; init; }        // "Success", "Failure", "Denied"
    public string? Details { get; init; }               // JSON additional context
}

// Append-only audit log service
public class AuditService
{
    private readonly AppDbContext _db;
    private readonly IHttpContextAccessor _httpContext;

    public AuditService(AppDbContext db, IHttpContextAccessor httpContext)
    {
        _db = db;
        _httpContext = httpContext;
    }

    public async Task LogAsync(string action, string result,
        string? resourceType = null, string? resourceId = null,
        string? details = null)
    {
        var context = _httpContext.HttpContext;
        var entry = new AuditLogEntry
        {
            Action = action,
            ActorId = context?.User.FindFirstValue(ClaimTypes.NameIdentifier) ?? "system",
            ActorType = context?.User.Identity?.IsAuthenticated == true ? "User" : "System",
            ResourceType = resourceType,
            ResourceId = resourceId,
            IpAddress = context?.Connection.RemoteIpAddress?.ToString(),
            UserAgent = context?.Request.Headers.UserAgent.ToString(),
            Result = result,
            Details = details
        };

        _db.AuditLogs.Add(entry);
        await _db.SaveChangesAsync();
    }
}

Quan trọng: Audit log table phải append-only - không cho phép UPDATE hoặc DELETE.

GDPR Requirements cho .NET Apps

Core GDPR Rights

RightMô tảImplementation
Right to AccessUser xem data của mìnhExport API endpoint
Right to RectificationUser sửa data saiUpdate API endpoint
Right to Erasure"Right to be forgotten"Deletion/anonymization pipeline
Right to PortabilityExport data ở format chuẩnJSON/CSV export
Right to ObjectTừ chối processingConsent management
Right to RestrictionHạn chế processingProcessing flags
csharp
public class UserConsent
{
    public Guid UserId { get; set; }
    public required string Purpose { get; set; }     // "marketing", "analytics"
    public bool IsGranted { get; set; }
    public DateTimeOffset GrantedAt { get; set; }
    public DateTimeOffset? RevokedAt { get; set; }
    public required string ConsentVersion { get; set; } // "v2.1"
    public required string IpAddress { get; set; }
}

// Consent check middleware
public class ConsentCheckFilter : IAsyncActionFilter
{
    private readonly ConsentService _consentService;

    public ConsentCheckFilter(ConsentService consentService)
        => _consentService = consentService;

    public async Task OnActionExecutionAsync(
        ActionExecutingContext context,
        ActionExecutionDelegate next)
    {
        var userId = context.HttpContext.User
            .FindFirstValue(ClaimTypes.NameIdentifier);

        if (userId is not null)
        {
            var hasConsent = await _consentService
                .HasValidConsentAsync(userId, "data-processing");

            if (!hasConsent)
            {
                context.Result = new StatusCodeResult(451); // Unavailable For Legal Reasons
                return;
            }
        }

        await next();
    }
}

Right to Erasure Implementation

csharp
public class GdprDeletionService
{
    private readonly AppDbContext _db;
    private readonly IBlobStorage _blobStorage;
    private readonly ILogger<GdprDeletionService> _logger;

    public async Task<DeletionResult> DeleteUserDataAsync(string userId)
    {
        var result = new DeletionResult { UserId = userId };

        // 1. Anonymize orders (keep for business records)
        var orders = await _db.Orders.Where(o => o.UserId == userId).ToListAsync();
        foreach (var order in orders)
        {
            order.UserId = "DELETED";
            order.CustomerName = "ANONYMIZED";
            order.Email = null;
            order.ShippingAddress = "ANONYMIZED";
        }
        result.OrdersAnonymized = orders.Count;

        // 2. Delete user profile completely
        var user = await _db.Users.FindAsync(userId);
        if (user is not null)
        {
            _db.Users.Remove(user);
            result.ProfileDeleted = true;
        }

        // 3. Delete user files from blob storage
        var deletedBlobs = await _blobStorage.DeleteUserFilesAsync(userId);
        result.FilesDeleted = deletedBlobs;

        // 4. Audit the deletion (keep audit log - legal requirement)
        _logger.LogInformation(
            "GDPR_DELETION: UserId={UserId} Orders={Orders} Files={Files}",
            "HASH:" + HashUserId(userId), // Log hashed ID only
            result.OrdersAnonymized,
            result.FilesDeleted);

        await _db.SaveChangesAsync();
        return result;
    }

    private static string HashUserId(string userId)
        => Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(userId)))[..16];
}

Azure Compliance Manager

Sử dụng Compliance Manager

bash
# Check compliance score
az security assessment list \
    --query "[?contains(displayName, 'SOC')]" \
    --output table

# Enable Microsoft Defender for Cloud
az security pricing create \
    --name VirtualMachines \
    --tier Standard

# Enable diagnostic settings cho audit
az monitor diagnostic-settings create \
    --name audit-logs \
    --resource /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/sites/{app} \
    --workspace /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.OperationalInsights/workspaces/{workspace} \
    --logs '[{"category":"AppServiceAuditLogs","enabled":true,"retentionPolicy":{"enabled":true,"days":365}}]'

Compliance Dashboard KQL Queries

kusto
// Audit log analysis - ai đã access sensitive data?
AppServiceAuditLogs
| where TimeGenerated > ago(30d)
| where OperationName contains "sensitive"
| summarize AccessCount = count() by UserDisplayName, bin(TimeGenerated, 1d)
| order by AccessCount desc

// Failed authentication attempts
SigninLogs
| where TimeGenerated > ago(7d)
| where ResultType != 0  // Non-zero = failure
| summarize FailureCount = count() by UserPrincipalName, IPAddress
| where FailureCount > 10
| order by FailureCount desc

Data Classification Strategy

Classification Levels

LevelMô tảVí dụControls
PublicCó thể công khaiMarketing content, docsBasic access control
InternalChỉ nhân viênInternal wiki, processesAuthentication required
ConfidentialBusiness sensitiveFinancial reports, roadmapEncryption + access control
RestrictedPII, regulated dataSSN, health records, paymentEncryption + audit + DLP

Implementation trong .NET

csharp
// Data classification attributes
[AttributeUsage(AttributeTargets.Property)]
public class DataClassificationAttribute : Attribute
{
    public DataClassificationLevel Level { get; }
    public DataClassificationAttribute(DataClassificationLevel level) => Level = level;
}

public enum DataClassificationLevel
{
    Public,
    Internal,
    Confidential,
    Restricted
}

// Usage trong entity models
public class Customer
{
    public int Id { get; set; }

    [DataClassification(DataClassificationLevel.Confidential)]
    public required string FullName { get; set; }

    [DataClassification(DataClassificationLevel.Restricted)]
    public required string Email { get; set; }

    [DataClassification(DataClassificationLevel.Restricted)]
    [PersonalData]  // ASP.NET Identity built-in attribute
    public string? PhoneNumber { get; set; }

    [DataClassification(DataClassificationLevel.Public)]
    public required string PreferredLanguage { get; set; }
}

Data Retention Policies

Data TypeRetention PeriodAfter Expiry
Audit logs7 years (SOC 2)Archive to cold storage
User PIIUntil deletion requestDelete/anonymize
Transaction records7 years (tax)Archive
Application logs90 daysDelete
Session data24 hoursAuto-expire
Backup data30 daysAuto-rotate

Trade-offs

Quyết địnhProCon
Strict data classificationClear controls, audit-friendlyProcess overhead, slower development
Automated compliance checksContinuous assuranceFalse positives, tool cost
Encryption everywhereMaximum protectionPerformance impact, complexity
Detailed audit loggingFull traceabilityStorage cost, PII in logs risk
GDPR hard deleteTrue erasureData integrity issues, cascading deletes
GDPR soft delete (anonymize)Preserves referential integrityPhải ensure k-anonymity