Logging with Redaction
Use Microsoft.Extensions.Logging with automatic sensitive field redaction.
Overview
When logging DynamoDB operations, you may need to redact sensitive data like PII, financial information, or authentication tokens. FluentDynamoDB integrates with Microsoft.Extensions.Logging and supports automatic redaction of marked fields.
Configuration
Basic Logging Setup
using Microsoft.Extensions.Logging;
using Oproto.FluentDynamoDb;
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddConsole();
builder.SetMinimumLevel(LogLevel.Debug);
});
var options = new FluentDynamoDbOptions()
.WithLogging(loggerFactory);
var table = new UserTable(dynamoDbClient, "users", options);
Dependency Injection
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(sp =>
{
var loggerFactory = sp.GetRequiredService<ILoggerFactory>();
var options = new FluentDynamoDbOptions()
.WithLogging(loggerFactory);
return new UserTable(dynamoDbClient, "users", options);
});
Marking Sensitive Fields
Use the [Sensitive] attribute to mark fields that should be redacted in logs:
[DynamoDbTable("users")]
public partial class User
{
[PartitionKey]
[DynamoDbAttribute("pk")]
public string Pk { get; set; } = string.Empty;
[SortKey]
[DynamoDbAttribute("sk")]
public string Sk { get; set; } = string.Empty;
[DynamoDbAttribute("userId")]
public string UserId { get; set; } = string.Empty;
[DynamoDbAttribute("name")]
public string Name { get; set; } = string.Empty;
// Sensitive fields - will be redacted in logs
[Sensitive]
[DynamoDbAttribute("email")]
public string Email { get; set; } = string.Empty;
[Sensitive]
[DynamoDbAttribute("ssn")]
public string SocialSecurityNumber { get; set; } = string.Empty;
[Sensitive]
[DynamoDbAttribute("creditCard")]
public string CreditCardNumber { get; set; } = string.Empty;
[DynamoDbAttribute("status")]
public string Status { get; set; } = string.Empty;
}
Redaction Patterns
Default Redaction
By default, sensitive fields are replaced with [REDACTED]:
// When logging this operation:
await table.Users.PutAsync(new User
{
UserId = "user123",
Name = "John Doe",
Email = "[email protected]", // Will be logged as [REDACTED]
SocialSecurityNumber = "123-45-6789" // Will be logged as [REDACTED]
});
// Log output:
// PUT User: { UserId: "user123", Name: "John Doe", Email: "[REDACTED]", SocialSecurityNumber: "[REDACTED]" }
Custom Redaction
Configure custom redaction patterns:
var options = new FluentDynamoDbOptions()
.WithLogging(loggerFactory, new RedactionOptions
{
RedactionText = "***",
PartialRedaction = true,
PartialRedactionVisibleChars = 4
});
With partial redaction enabled:
Email: "john***" (first 4 chars visible)
CreditCard: "****5678" (last 4 chars visible)
Usage Examples
Query with Logging
// Queries are logged with redacted filter values
var users = await table.Users.Query()
.Where(x => x.Status == "active")
.ToListAsync();
// Log output:
// QUERY Users WHERE Status = "active" - Returned 5 items
Update with Logging
await table.Users.Update("user123")
.Set(x => new { Email = "[email protected]" })
.UpdateAsync();
// Log output:
// UPDATE User "user123" SET Email = "[REDACTED]"
Conditional Operations
await table.Users.Put(user)
.Where(x => x.Email.AttributeNotExists())
.PutAsync();
// Log output:
// PUT User WHERE Email attribute_not_exists - Success
Get Operations
var user = await table.Users.GetAsync("user123");
// Log output:
// GET User "user123" - Found
// Response: { UserId: "user123", Name: "John Doe", Email: "[REDACTED]" }
Delete Operations
await table.Users.DeleteAsync("user123");
// Log output:
// DELETE User "user123" - Success
Compliance
Automatic redaction helps meet compliance requirements:
GDPR
- Personal data is automatically redacted in logs
- Supports data minimization principles
- Audit trails don't expose PII
HIPAA
- Protected Health Information (PHI) can be marked sensitive
- Logs remain compliant with disclosure rules
PCI-DSS
- Credit card numbers are redacted
- Cardholder data protected in logs
- Supports audit requirements without exposing sensitive data
Best Practices
- Mark all PII as sensitive - Email, phone, SSN, addresses
- Mark financial data - Credit cards, bank accounts, salaries
- Mark authentication data - Passwords, tokens, API keys
- Use structured logging - Enables better log analysis while maintaining redaction
- Test redaction - Verify sensitive data doesn't appear in logs during development