Architecture Overview
This guide implements a comprehensive security architecture for Azure-based applications using defense-in-depth principles. Our security model encompasses multiple layers:
Infrastructure Layer:
Azure App Service with TLS 1.3 enforcement
Azure API Management as secure gateway
Azure Database for PostgreSQL with encryption at rest and in transit
Azure Key Vault for centralized secrets management
Azure Front Door for global load balancing and WAF protection
Application Layer:
React frontend with client-side encryption
JWT-based authentication with proper token validation
AES-256-GCM encryption for sensitive data
RSA-4096 for asymmetric operations
Data Layer:
Database-level encryption using Azure Key Vault keys
Application-level field encryption for PII
Secure connection strings with SSL enforcement
Audit logging for all data access
Network Layer:
HTTPS-only communication with strong cipher suites
Perfect Forward Secrecy through ephemeral key exchange
CORS policies with strict origin validation
Rate limiting and DDoS protection
Transport Layer Security (TLS 1.3)
Overview
TLS 1.3 provides improved security and performance over previous versions. It reduces handshake round trips, removes vulnerable cipher suites, and ensures forward secrecy by default. Azure App Service and API Management both support TLS 1.3 configuration.
Key Benefits:
Reduced attack surface with fewer cipher suite options
Improved performance with 1-RTT handshakes
Built-in forward secrecy
Protection against downgrade attacks
Azure App Service Configuration
// Program.cs - TLS 1.3 enforcement
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = StatusCodes.Status308PermanentRedirect;
options.HttpsPort = 443;
});
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(httpsOptions =>
{
httpsOptions.SslProtocols = SslProtocols.Tls13;
httpsOptions.CheckCertificateRevocation = true;
});
});
ARM Template for TLS Configuration
{
"type": "Microsoft.Web/sites",
"apiVersion": "2021-03-01",
"properties": {
"httpsOnly": true,
"siteConfig": {
"minTlsVersion": "1.3",
"ftpsState": "Disabled",
"http20Enabled": true,
"alwaysOn": true
}
}
}
Azure Key Vault Integration
Overview
Azure Key Vault serves as the central repository for all cryptographic keys, secrets, and certificates. It provides hardware security module (HSM) backing, access policies, and audit logging. Integration with Managed Identity ensures secure, password-less authentication.
Key Features:
HSM-backed key storage
Automatic key rotation
Fine-grained access policies
Comprehensive audit logging
Integration with Azure services
Key Vault Service Implementation
public class AzureKeyVaultService
{
private readonly KeyClient _keyClient;
private readonly SecretClient _secretClient;
private readonly ILogger<AzureKeyVaultService> _logger;
public AzureKeyVaultService(IConfiguration configuration, ILogger<AzureKeyVaultService> logger)
{
var keyVaultUrl = configuration["AzureKeyVault:Url"];
var credential = new DefaultAzureCredential();
_keyClient = new KeyClient(new Uri(keyVaultUrl), credential);
_secretClient = new SecretClient(new Uri(keyVaultUrl), credential);
_logger = logger;
}
public async Task<string> GetSecretAsync(string secretName)
{
try
{
var secret = await _secretClient.GetSecretAsync(secretName);
return secret.Value.Value;
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to retrieve secret: {SecretName}", secretName);
throw;
}
}
public async Task<KeyVaultKey> CreateEncryptionKeyAsync(string keyName)
{
var keyOptions = new CreateKeyOptions(keyName, KeyType.Rsa)
{
KeySize = 4096,
KeyOperations = { KeyOperation.Encrypt, KeyOperation.Decrypt }
};
return await _keyClient.CreateKeyAsync(keyOptions);
}
}
Advanced Encryption Standards (AES-256)
Overview
AES-256 in Galois Counter Mode (GCM) provides authenticated encryption, ensuring both confidentiality and integrity. GCM mode offers superior performance and security compared to CBC mode, with built-in authentication that prevents tampering.
GCM Advantages:
Authenticated encryption (confidentiality + integrity)
Parallel processing capability
Resistance to padding oracle attacks
NIST recommended for sensitive data
AES-GCM Implementation
public class AesGcmEncryptionService
{
private readonly AzureKeyVaultService _keyVaultService;
private const int KeySize = 256;
private const int NonceSize = 12;
private const int TagSize = 16;
public async Task<EncryptedData> EncryptAsync(string plaintext, string keyName)
{
var key = await GetOrCreateEncryptionKeyAsync(keyName);
var nonce = GenerateNonce();
var plaintextBytes = Encoding.UTF8.GetBytes(plaintext);
var ciphertext = new byte[plaintextBytes.Length];
var tag = new byte[TagSize];
using var aesGcm = new AesGcm(key);
aesGcm.Encrypt(nonce, plaintextBytes, ciphertext, tag);
return new EncryptedData
{
Ciphertext = Convert.ToBase64String(ciphertext),
Nonce = Convert.ToBase64String(nonce),
Tag = Convert.ToBase64String(tag),
KeyName = keyName
};
}
private static byte[] GenerateNonce()
{
var nonce = new byte[NonceSize];
using var rng = RandomNumberGenerator.Create();
rng.GetBytes(nonce);
return nonce;
}
}
Database Security (PostgreSQL)
Overview
Azure Database for PostgreSQL provides multiple layers of security including encryption at rest, encryption in transit, and network isolation. Integration with Azure Key Vault enables customer-managed encryption keys (CMEK) for enhanced control over data protection.
Security Features:
Transparent Data Encryption (TDE) with customer-managed keys
SSL/TLS encryption for connections
VNet integration for network isolation
Advanced Threat Protection
Audit logging and monitoring
Secure Database Context
public class SecurePostgreSqlContext : DbContext
{
private readonly AzureKeyVaultService _keyVaultService;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var connectionString = BuildSecureConnectionString().Result;
optionsBuilder.UseNpgsql(connectionString, options =>
{
options.EnableRetryOnFailure(maxRetryCount: 3);
})
.EnableSensitiveDataLogging(false);
}
private async Task<string> BuildSecureConnectionString()
{
var server = await _keyVaultService.GetSecretAsync("postgresql-server");
var password = await _keyVaultService.GetSecretAsync("postgresql-password");
return new NpgsqlConnectionStringBuilder
{
Host = server,
Password = password,
SslMode = SslMode.Require,
TrustServerCertificate = false,
Pooling = true,
MaxPoolSize = 20
}.ToString();
}
}
Client-Side Security (React & JavaScript)
Overview
Client-side security involves implementing encryption in the browser using the Web Crypto API, secure storage mechanisms, and protection against common web vulnerabilities. The Web Crypto API provides cryptographically strong random number generation and encryption capabilities.
Client-Side Security Features:
Web Crypto API for encryption operations
Secure session storage with encryption
Content Security Policy enforcement
XSS and CSRF protection
Secure API communication
Client-Side Encryption
class SecureCryptoManager {
constructor() {
this.algorithm = 'AES-GCM';
this.keyLength = 256;
}
async generateKey() {
return await crypto.subtle.generateKey(
{ name: this.algorithm, length: this.keyLength },
true,
['encrypt', 'decrypt']
);
}
async encryptData(data, key) {
const encoder = new TextEncoder();
const dataBuffer = encoder.encode(JSON.stringify(data));
const iv = crypto.getRandomValues(new Uint8Array(12));
const encryptedBuffer = await crypto.subtle.encrypt(
{ name: this.algorithm, iv: iv },
key,
dataBuffer
);
return {
encryptedData: Array.from(new Uint8Array(encryptedBuffer)),
iv: Array.from(iv)
};
}
}
class SecureApiClient {
async secureRequest(endpoint, method = 'GET', data = null) {
const headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
};
const authToken = await this.getAuthToken();
if (authToken) {
headers['Authorization'] = `Bearer ${authToken}`;
}
return await fetch(endpoint, {
method,
headers,
credentials: 'include',
body: data ? JSON.stringify(data) : null
});
}
}
Security Headers & Content Security Policy
Overview
Security headers provide essential protection against common web vulnerabilities including XSS, clickjacking, and content injection attacks. Content Security Policy (CSP) acts as an allowlist for resource loading, significantly reducing the attack surface.
Essential Security Headers:
Strict-Transport-Security (HSTS)
Content-Security-Policy (CSP)
X-Frame-Options (Clickjacking protection)
X-Content-Type-Options (MIME sniffing protection)
Referrer-Policy (Information leakage protection)
Security Headers Middleware
public class SecurityHeadersMiddleware
{
private readonly RequestDelegate _next;
public async Task InvokeAsync(HttpContext context)
{
// HSTS Header
context.Response.Headers.Add("Strict-Transport-Security",
"max-age=31536000; includeSubDomains; preload");
// Content Security Policy
var csp = "default-src 'self'; " +
"script-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; " +
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; " +
"font-src 'self' https://fonts.gstatic.com; " +
"img-src 'self' data: https:; " +
"connect-src 'self' https:; " +
"object-src 'none'; " +
"base-uri 'self'; " +
"form-action 'self'";
context.Response.Headers.Add("Content-Security-Policy", csp);
// Additional security headers
context.Response.Headers.Add("X-Frame-Options", "DENY");
context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
context.Response.Headers.Add("Referrer-Policy", "strict-origin-when-cross-origin");
await _next(context);
}
}
API Management Security
Overview
Azure API Management acts as a secure gateway, providing authentication, authorization, rate limiting, and request/response transformation. It implements OAuth 2.0, OpenID Connect, and custom authentication mechanisms while offering comprehensive logging and monitoring.
API Management Features:
JWT token validation
Rate limiting and throttling
IP filtering and geo-blocking
Request/response transformation
Comprehensive logging
API Management Policy
<policies>
<inbound>
<rate-limit calls="100" renewal-period="60" />
<validate-jwt header-name="Authorization" failed-validation-httpcode="401">
<openid-config url="https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid_configuration" />
</validate-jwt>
<cors allow-credentials="true">
<allowed-origins>
<origin>https://yourdomain.com</origin>
</allowed-origins>
<allowed-methods>
<method>GET</method>
<method>POST</method>
</allowed-methods>
</cors>
</inbound>
<outbound>
<set-header name="X-Content-Type-Options" exists-action="override">
<value>nosniff</value>
</set-header>
</outbound>
</policies>
Microservices Authentication (JWT)
Overview
JWT-based authentication provides stateless, scalable authentication for microservices. Tokens contain claims and are cryptographically signed to ensure integrity. Proper validation includes signature verification, expiration checking, and audience validation.
JWT Security Features:
Cryptographic signature validation
Expiration time enforcement
Audience and issuer validation
Custom claims support
JWT Service Implementation
public class JwtAuthenticationService
{
private readonly IConfiguration _configuration;
private readonly AzureKeyVaultService _keyVaultService;
public async Task<string> GenerateTokenAsync(ClaimsIdentity identity)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = await GetSigningKeyAsync();
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = identity,
Expires = DateTime.UtcNow.AddMinutes(30),
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(key),
SecurityAlgorithms.HmacSha256),
Issuer = _configuration["Jwt:Issuer"],
Audience = _configuration["Jwt:Audience"]
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
public async Task<ClaimsPrincipal> ValidateTokenAsync(string token)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = await GetSigningKeyAsync();
var validationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = true,
ValidIssuer = _configuration["Jwt:Issuer"],
ValidateAudience = true,
ValidAudience = _configuration["Jwt:Audience"],
ClockSkew = TimeSpan.Zero
};
return tokenHandler.ValidateToken(token, validationParameters, out _);
}
}
Perfect Forward Secrecy (ECDH)
Overview
Perfect Forward Secrecy ensures that session keys are not compromised even if long-term keys are breached. ECDH (Elliptic Curve Diffie-Hellman) key exchange generates ephemeral keys for each session, which are immediately destroyed after use.
PFS Benefits:
Session isolation - compromise of one session doesn't affect others
Ephemeral key generation and destruction
Protection against retroactive decryption
Compliance with security standards
ECDH Implementation
public class EcdhKeyExchangeService
{
public (string publicKey, ECDiffieHellman ecdh) GenerateKeyPair()
{
var ecdh = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP384);
var publicKey = Convert.ToBase64String(ecdh.PublicKey.ExportSubjectPublicKeyInfo());
return (publicKey, ecdh);
}
public byte[] DeriveSharedKey(ECDiffieHellman localKey, string remotePublicKey)
{
var remoteKeyBytes = Convert.FromBase64String(remotePublicKey);
using var remoteKey = ECDiffieHellman.Create();
remoteKey.ImportSubjectPublicKeyInfo(remoteKeyBytes, out _);
return localKey.DeriveKeyMaterial(remoteKey.PublicKey);
}
}
public class SessionKeyManager
{
public async Task<SessionKeyInfo> CreateSessionAsync(string sessionId)
{
var (publicKey, ecdh) = _keyExchange.GenerateKeyPair();
// Store ephemeral key temporarily
_cache.Set($"session_{sessionId}", ecdh, TimeSpan.FromMinutes(30));
return new SessionKeyInfo
{
SessionId = sessionId,
PublicKey = publicKey,
ExpiresAt = DateTime.UtcNow.AddMinutes(30)
};
}
}
Data Protection & Compliance (GDPR)
Overview
Data protection implementation ensures compliance with GDPR and other privacy regulations. This includes encryption of personal data, secure data handling, audit trails, and the right to erasure. Multiple layers of encryption provide defense in depth.
Compliance Features:
Multi-layer encryption for personal data
Audit logging for data access
Right to erasure implementation
Data minimization practices
Consent management
Data Protection Service
public class DataProtectionService
{
private readonly AesGcmEncryptionService _encryption;
private readonly IDataProtector _dataProtector;
public async Task<string> ProtectPersonalDataAsync(string personalData, string purpose)
{
// Layer 1: ASP.NET Core Data Protection
var protected1 = _dataProtector.Protect(personalData);
// Layer 2: AES-GCM encryption
var encrypted = await _encryption.EncryptAsync(protected1, $"personal_data_{purpose}");
return JsonSerializer.Serialize(encrypted);
}
public async Task<bool> ErasePersonalDataAsync(string userId)
{
// Implementation includes:
// 1. Mark data for deletion
// 2. Overwrite with random bytes
// 3. Remove encryption keys
// 4. Log erasure event
return true;
}
}
Security Monitoring & Logging
Overview
Comprehensive security monitoring provides real-time threat detection, audit trails, and compliance reporting. Integration with Azure Application Insights and Azure Security Center enables centralized monitoring and alerting for security events.
Monitoring Capabilities:
Real-time security event logging
Threat detection and alerting
Compliance reporting
Performance monitoring
Audit trail maintenance
Security Event Logger
public class SecurityEventLogger
{
private readonly TelemetryClient _telemetryClient;
private readonly ILogger<SecurityEventLogger> _logger;
public void LogSecurityEvent(SecurityEventType eventType, string details, HttpContext? context = null)
{
var properties = new Dictionary<string, string>
{
["EventType"] = eventType.ToString(),
["Details"] = details,
["Timestamp"] = DateTime.UtcNow.ToString("O")
};
if (context != null)
{
properties["IpAddress"] = GetClientIpAddress(context);
properties["UserAgent"] = context.Request.Headers["User-Agent"].ToString();
properties["RequestPath"] = context.Request.Path;
}
_telemetryClient.TrackEvent($"SecurityEvent_{eventType}", properties);
var logLevel = GetLogLevel(eventType);
_logger.Log(logLevel, "Security event: {EventType} - {Details}", eventType, details);
}
private static LogLevel GetLogLevel(SecurityEventType eventType)
{
return eventType switch
{
SecurityEventType.LoginSuccess => LogLevel.Information,
SecurityEventType.LoginFailure => LogLevel.Warning,
SecurityEventType.UnauthorizedAccess => LogLevel.Error,
SecurityEventType.DataBreach => LogLevel.Critical,
_ => LogLevel.Information
};
}
}
Application Configuration
Overview
Secure application configuration involves proper service registration, middleware ordering, and security policy setup. The configuration ensures all security components work together effectively while maintaining performance and usability.
Complete Security Setup
// Program.cs - Security configuration
var builder = WebApplication.CreateBuilder(args);
// Azure Key Vault
builder.Configuration.AddAzureKeyVault(
new Uri(builder.Configuration["AzureKeyVault:Url"]!),
new DefaultAzureCredential());
// Register security services
builder.Services.AddSingleton<AzureKeyVaultService>();
builder.Services.AddSingleton<AesGcmEncryptionService>();
builder.Services.AddSingleton<SecurityEventLogger>();
builder.Services.AddScoped<JwtAuthenticationService>();
// Data Protection with Azure Key Vault
builder.Services.AddDataProtection()
.PersistKeysToAzureBlobStorage(builder.Configuration.GetConnectionString("DataProtection"))
.ProtectKeysWithAzureKeyVault(
new Uri(builder.Configuration["AzureKeyVault:DataProtectionKey"]!),
new DefaultAzureCredential());
// Authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer();
// CORS
builder.Services.AddCors(options =>
{
options.AddPolicy("SecurePolicy", policy =>
policy.WithOrigins("https://yourdomain.com")
.AllowAnyMethod()
.AllowCredentials());
});
var app = builder.Build();
// Security middleware pipeline
app.UseHttpsRedirection();
app.UseMiddleware<SecurityHeadersMiddleware>();
app.UseCors("SecurePolicy");
app.UseAuthentication();
app.UseAuthorization();
app.Run();
Security Testing
Overview
Security testing validates the implementation of security controls and identifies vulnerabilities. Automated tests verify encryption functionality, authentication mechanisms, and security headers while integration tests ensure end-to-end security.
Security Test Examples
[TestClass]
public class SecurityTests
{
[TestMethod]
public async Task Should_Include_Security_Headers()
{
var response = await _client.GetAsync("/api/test");
Assert.IsTrue(response.Headers.Contains("Strict-Transport-Security"));
Assert.IsTrue(response.Headers.Contains("Content-Security-Policy"));
Assert.IsTrue(response.Headers.Contains("X-Frame-Options"));
}
[TestMethod]
public async Task Should_Encrypt_Decrypt_Correctly()
{
var encryptionService = _server.Services.GetRequiredService<AesGcmEncryptionService>();
const string testData = "Sensitive information";
var encrypted = await encryptionService.EncryptAsync(testData, "test-key");
var decrypted = await encryptionService.DecryptAsync(encrypted);
Assert.AreEqual(testData, decrypted);
}
[TestMethod]
public async Task Should_Reject_Invalid_Tokens()
{
_client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "invalid-token");
var response = await _client.GetAsync("/api/secure");
Assert.AreEqual(HttpStatusCode.Unauthorized, response.StatusCode);
}
}
Best Practices Summary
Implementation Checklist
Transport Security:
✅ TLS 1.3 configured on all endpoints
✅ Strong cipher suites enabled
✅ HSTS headers implemented
✅ Certificate management automated
Encryption:
✅ AES-256-GCM for symmetric encryption
✅ RSA-4096 for asymmetric operations
✅ Proper key derivation functions
✅ Secure random number generation
Key Management:
✅ Azure Key Vault integration
✅ Automated key rotation
✅ Proper access policies
✅ Hardware security modules
Authentication & Authorization:
✅ JWT with proper validation
✅ Strong password policies
✅ Multi-factor authentication
✅ Role-based access control
Database Security:
✅ Encryption at rest and in transit
✅ Secure connection strings
✅ Parameterized queries
✅ Regular security updates
Application Security:
✅ Input validation and sanitization
✅ Output encoding
✅ CSRF protection
✅ XSS prevention
Monitoring & Compliance:
✅ Security event logging
✅ Real-time monitoring
✅ Compliance reporting
✅ Incident response procedures
Performance Considerations
Encryption Performance:
Use hardware acceleration when available
Implement connection pooling for Key Vault
Cache encryption keys appropriately
Optimize key derivation processes
Security vs. Usability:
Balance s