SOC 2 Certification Readiness Checklist
This page describes technical features that can support your compliance work. It is not legal advice, and it does not establish that any system is compliant with any law, regulation or standard. You remain responsible for your own compliance assessment, independent testing and validation, and review by qualified legal and compliance professionals. See the Compliance Disclaimer.
Framework: Excalibur Standard: SOC 2 (Service Organization Control 2) - Trust Services Criteria Categories: Security (CC1-CC9) + Optional (Availability, Processing Integrity, Confidentiality, Privacy) Status: Automated control validation + evidence collection Last Updated: 2026-09-12
The SSP Statement blocks on this page are written to be copied into your own System Security Plan, so treat each one as a draft about your system rather than as a finding about it. A review of these statements is in progress and is not complete.
A statement that has not yet been reviewed may describe a capability that is opt-in and not active unless you register it, that is configured differently in your deployment, or that the framework does not provide. Several controls documented here are inactive until explicitly enabled.
Before pasting any statement into a document an assessor will read, confirm it against the configuration you actually run.
Overview
This checklist provides step-by-step guidance for SOC 2 certification preparation using the Excalibur framework. The framework provides automated control validation, evidence collection, and report generation for all Trust Services Criteria.
SOC 2 Scope: Service organizations (SaaS, cloud providers, MSPs) Report Types: Type I (point-in-time) and Type II (period assessment) Compliance Approach: Framework-provided validators + consumer organizational controls
Trust Services Categories
| Category | Criteria | Description | Required? | Framework Support |
|---|---|---|---|---|
| Security | CC1-CC9 | Protection against unauthorized access | YES (always) | ✅ Full |
| Availability | A1-A3 | System uptime and reliability | Optional | ✅ Full |
| Processing Integrity | PI1-PI3 | Data processing accuracy | Optional | ✅ Full |
| Confidentiality | C1-C3 | Protection of confidential data | Optional | ✅ Full |
| Privacy | P1-P8 | Personal information handling | Optional | ⚠️ Partial (see GDPR checklist) |
Recommendation: Start with Security (required) + Availability + Confidentiality for comprehensive cloud service coverage.
Control Mapping Table
Security (Common Criteria) - CC1-CC9
| Criterion | Title | Framework Implementation | Consumer Action | Evidence Location |
|---|---|---|---|---|
| CC1 | Control Environment | N/A | Management commitment, ethics policies | Business process |
| CC2 | Communication | N/A | Communication policies | Business process |
| CC3 | Risk Assessment | N/A | Risk assessment procedures | Business process |
| CC4 | Monitoring Activities | ✅ IAuditLogger (tamper-evident hash chain) | Configure audit logging | Audit logging |
| CC5 | Control Activities | ✅ [RequirePermission], input validation | Implement authorization | Authorization |
| CC6 | Logical Access | ✅ RBAC, encryption, key management | Configure access controls | Role-based authorization |
| CC7 | System Operations | ✅ Health checks, monitoring | Configure OpenTelemetry | OpenTelemetry |
| CC8 | Change Management | ✅ CI/CD pipeline, version control | Review pipeline | Development process (SA-15) |
| CC9 | Risk Mitigation | ✅ SAST (CodeQL), secrets (Gitleaks), dependency scanning | Review scan results, and add DAST/container scanning if your assessment needs them | What this pipeline scans |
Availability - A1-A3
| Criterion | Title | Framework Implementation | Consumer Action | Evidence Location |
|---|---|---|---|---|
| A1 | Infrastructure Management | ✅ Health checks, retry policies | Configure health checks | Health checks |
| A2 | Capacity Management | ⚠️ Partial | Monitor capacity, scale as needed | Cloud provider docs |
| A3 | Backup & Recovery | ⚠️ Partial | Configure backups | Cloud provider docs |
Processing Integrity - PI1-PI3
| Criterion | Title | Framework Implementation | Consumer Action | Evidence Location |
|---|---|---|---|---|
| PI1 | Input Validation | ✅ IInputValidator, FluentValidation | Validate inputs | Input validation |
| PI2 | Processing Accuracy | ✅ Outbox pattern, idempotency | Configure outbox | Outbox pattern |
| PI3 | Output Completeness | ✅ Event ordering, correlation IDs | Verify telemetry | Observability |
Confidentiality - C1-C3
| Criterion | Title | Framework Implementation | Consumer Action | Evidence Location |
|---|---|---|---|---|
| C1 | Data Classification | ✅ [PersonalData], [Sensitive] attributes | Classify data | Data masking |
| C2 | Data Protection | ✅ AES-256-GCM encryption | Configure encryption | AES-256-GCM encryption |
| C3 | Data Disposal | ✅ Cryptographic erasure (IErasureService) | Configure erasure | GDPR erasure |
Legend:
- ✅ Framework provides automated validation
- ⚠️ Framework provides tools, consumer configures
- N/A: Organizational control (not technical)
Implementation Checklist
Phase 1: Prerequisites (Week 1)
1.1 Understand SOC 2 Scope
- Determine which Trust Services Categories to pursue (Security + optional)
- Define system boundary (what services are in scope)
- Identify service commitments (uptime SLAs, security promises, etc.)
- Document system description for auditor
Reference: AICPA Trust Services Criteria
1.2 Install Framework Packages
dotnet add package Excalibur.Compliance
1.3 Basic SOC 2 Configuration
Development Setup:
using Excalibur.Compliance;
var builder = WebApplication.CreateBuilder(args);
// Add SOC 2 compliance with built-in validators
builder.Services.AddSoc2ComplianceWithBuiltInValidators(options =>
{
options.EnabledCategories = new[]
{
TrustServicesCategory.Security,
TrustServicesCategory.Availability,
TrustServicesCategory.Confidentiality
};
});
// Add in-memory report store for development
builder.Services.AddInMemorySoc2ReportStore();
- Configure SOC 2 compliance service
- Select Trust Services Categories
- Add in-memory report store for development
Production Setup with Continuous Monitoring:
builder.Services.AddSoc2ComplianceWithMonitoring(options =>
{
options.EnabledCategories =
[
TrustServicesCategory.Security,
TrustServicesCategory.Availability,
TrustServicesCategory.ProcessingIntegrity,
TrustServicesCategory.Confidentiality
];
// Monitoring settings are nested under Monitoring.
options.Monitoring.EnableContinuousMonitoring = true;
options.Monitoring.MonitoringInterval = TimeSpan.FromHours(1);
options.Monitoring.AlertThreshold = GapSeverity.Medium;
});
// Add custom alert handler for PagerDuty/Slack/Email integration
builder.Services.AddComplianceAlertHandler<PagerDutyAlertHandler>();
- Configure continuous monitoring (hourly recommended)
- Set alert severity threshold (Medium or High)
- Integrate with incident management (PagerDuty, Slack, etc.)
Phase 2: Security Controls (CC1-CC9) - Week 2-3
2.1 CC4: Monitoring Activities (Audit Logging)
Control Requirement: The entity monitors the system and takes action to remediate identified deficiencies in a timely manner.
Framework Implementation:
IAuditLoggerinterface with tamper-evident hash chain- Structured audit logs with correlation IDs
- Immutable append-only audit trails
Consumer Checklist:
- Inject
IAuditLoggerinto services
Code Example:
using Excalibur.Compliance;
public class UserService
{
private readonly IAuditLogger _auditLogger;
public async Task UpdateUserAsync(User user, CancellationToken ct)
{
// Perform update
await _repository.UpdateAsync(user, ct);
// Audit the action
await _auditLogger.LogAsync(new AuditEvent
{
EventId = Guid.NewGuid().ToString(),
EventType = AuditEventType.DataModification,
Action = "User.Update",
ActorId = _currentUser.Id,
Outcome = AuditOutcome.Success,
Timestamp = DateTimeOffset.UtcNow,
ResourceId = user.Id.ToString(),
ResourceType = "User"
}, ct);
}
}
- Configure audit event types
- Implement
IAuditStorepersistence layer (SQL Server recommended) - Verify hash chain integrity with tests
- Configure RBAC for audit log access
Automated Validation:
// AuditLogControlValidator automatically checks:
// - Audit logging is enabled
// - Hash chain integrity is maintained
// - Retention policies are configured
// - RBAC is enforced for audit access
- Run
AuditLogControlValidatorto verify compliance - Review validation results (2 controls: SEC-004 Audit Logging, SEC-005 Security Monitoring)
Evidence:
- Audit logging - Audit logging guide
- Audit log samples (anonymized)
- Hash chain integrity verification tests
- Conformance results from the arms you wrapped (
AuditStoreConformanceTestKit)
The kit is bound against real SQL Server and real PostgreSQL, not the in-memory store alone. That evidences our schema and our configuration, not your deployment — our suites run against a disposable container. Cite the arms your run executed and passed against your database, not the bindings we ship.
SSP Statement:
"CC4 is satisfied through tamper-evident audit logging using cryptographic hash chains. The framework's
IAuditLoggercaptures all security-relevant events with correlation IDs, timestamps, and outcomes. Audit logs are append-only with RBAC access controls."
2.2 CC5: Control Activities (Authorization + Input Validation)
Control Requirement: The entity identifies and develops control activities that contribute to the mitigation of risks.
Framework Implementation:
[RequirePermission]attribute for declarative authorizationIInputValidatorfor input validation- FluentValidation integration
Consumer Checklist:
- Apply
[RequirePermission]to protected operations
Authorization Example:
using Excalibur.A3.Authorization;
[RequirePermission("users.delete")]
public class DeleteUserAction : IDispatchAction
{
public Guid UserId { get; set; }
}
// Authorization middleware enforces permission check
- Implement input validation for all commands
Validation Example:
using FluentValidation;
public class CreateUserCommandValidator : AbstractValidator<CreateUserCommand>
{
public CreateUserCommandValidator()
{
RuleFor(x => x.Email)
.NotEmpty()
.EmailAddress();
RuleFor(x => x.Password)
.NotEmpty()
.MinimumLength(12)
.Matches(@"[A-Z]").WithMessage("Password must contain uppercase")
.Matches(@"[a-z]").WithMessage("Password must contain lowercase")
.Matches(@"[0-9]").WithMessage("Password must contain digit");
}
}
- Test authorization enforcement (unit + integration tests)
- Test input validation (reject invalid inputs)
Evidence:
- Authorization - Authorization guide
- Unit tests for authorization and validation
- Code review evidence (authorization applied to sensitive operations)
SSP Statement:
"CC5 is satisfied through declarative authorization (
[RequirePermission]) and comprehensive input validation (FluentValidation). All protected operations require explicit permissions, and all user inputs are validated before processing."
2.3 CC6: Logical Access (Encryption + Key Management)
Control Requirement: The entity restricts logical access through the use of access control software and supporting utilities.
Framework Implementation:
IEncryptionProviderabstraction for pluggable encryption- AES-256-GCM encryption at rest
- TLS 1.2+ encryption in transit
- Key rotation support
Consumer Checklist:
- Configure encryption provider (Azure Key Vault, AWS KMS, etc.)
Code Example:
using Excalibur.Compliance;
services.AddEncryption(encryption => encryption
.UseKeyManagement<AesGcmEncryptionProvider>("aes-gcm-primary")
.ConfigureOptions(options => options.DefaultPurpose = "field-encryption"));
// Annotate sensitive fields
public class User
{
public Guid Id { get; set; }
[PersonalData] // [PersonalData] is encrypted ONLY on a record that also carries [DataSubjectId],
// and only on a path you wire (crypto-shredding / the encrypting event-store decorator).
// A record with no [DataSubjectId] member is left in cleartext.
public string Email { get; set; }
[PersonalData]
public string PhoneNumber { get; set; }
}
- Annotate sensitive fields with
[PersonalData] - Verify encryption at rest (inspect database)
- Configure TLS 1.2+ for all HTTP endpoints
- Document key rotation procedures
Automated Validation:
// EncryptionControlValidator automatically checks:
// - Encryption at rest is enabled (AES-256-GCM)
// - Key management is configured
// - Key rotation policies are active
- Run
EncryptionControlValidatorto verify compliance - Review validation results (3 controls: SEC-001, SEC-002, SEC-003)
Evidence:
- Encryption architecture - Encryption guide
- Encryption verification tests
- Key management procedures
- TLS configuration (testssl.sh scan results)
SSP Statement:
"CC6 is satisfied through AES-256-GCM encryption at rest and TLS 1.2+ encryption in transit. The framework's
IEncryptionProviderintegrates with Azure Key Vault for centralized key management with automated rotation."
2.4 CC7: System Operations (Health Checks + Monitoring)
Control Requirement: The entity manages the operational activities of the system to meet the entity's objectives.
Framework Implementation:
- OpenTelemetry integration for distributed tracing
- Health check endpoints
- Structured logging with correlation IDs
Consumer Checklist:
- Configure OpenTelemetry exporter (Application Insights, Jaeger, etc.)
Code Example:
using OpenTelemetry.Trace;
using OpenTelemetry.Metrics;
services.AddOpenTelemetry()
.WithTracing(builder => builder
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddApplicationInsightsExporter(options =>
{
options.ConnectionString = Configuration["ApplicationInsights:ConnectionString"];
}))
.WithMetrics(builder => builder
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddApplicationInsightsExporter());
// Health checks
services.AddHealthChecks()
.AddSqlServer(connectionString)
.AddRedis(redisConnectionString);
app.MapHealthChecks("/health");
- Set up alerts for failed health checks
- Configure log aggregation (ELK stack, Splunk, etc.)
- Implement runbooks for common incidents
Evidence:
- Observability - Monitoring guide
- OpenTelemetry configuration
- Health check endpoint verification
- Alert rules and runbooks
SSP Statement:
"CC7 is satisfied through OpenTelemetry integration for distributed tracing and metrics. Health check endpoints monitor system availability. Structured logging with correlation IDs enables incident investigation."
2.5 CC8: Change Management (CI/CD Pipeline)
Control Requirement: The entity implements change management processes to manage changes to the system.
Framework Implementation:
- Comprehensive CI/CD pipeline with quality gates
- Automated testing (unit, integration, functional)
- Security scanning (SAST via CodeQL, secrets via Gitleaks, dependency vulnerabilities)
- SBOM generation on every build
Consumer Checklist:
- Review CI/CD pipeline configuration
Pipeline Stages:
# .github/workflows/ci.yml
jobs:
build:
- Checkout code
- Setup .NET 10.0
- Restore dependencies
- Build solution
- Run unit tests
- Upload coverage (enforced regression floor of 44%)
security-sast:
- CodeQL analysis (SAST)
- Dependency vulnerability scan
- Secrets scanning (Gitleaks)
# NOTE: no DAST and no container scanning run in this pipeline.
# Security scanning is CodeQL (SAST), Gitleaks (secrets) and dependency scanning.
- API security testing
# (no container-scan job exists)
- Critical vulnerability blocking
sbom-generation:
- CycloneDX SBOM generation
- Upload artifacts (90-day retention)
- Verify all quality gates pass in your own pipeline, and retain those run records — the framework repository's runs are not evidence for your system
- Review deployment approval workflow
- Document rollback procedures
Evidence:
- Development process (SA-15) - the framework's own CI/CD pipeline, as supply-chain context
- Workflow run records from your own CI, retained per your retention policy, as the audit trail
- Deployment logs
- Rollback documentation
Statement for your report:
Write this about your own change-management process. CC8 is a control over how you authorise, test and deploy changes; the framework is a dependency of your system rather than a part of that process, so its repository's workflow runs cannot serve as your audit trail. Replace each bracketed item with what you actually do:
"CC8 is satisfied through our change-management process and CI/CD pipeline. Every change to [system name] undergoes [unit and integration tests], [static analysis tool], [secret scanning tool] and [dependency vulnerability scanning] before deployment, and a change that fails any gate is not promoted. Deployments require [approval step], and run records are retained for [retention period]."
The framework's own scanning and SBOM are evidence about a dependency, which supports your vendor and supply-chain criteria — not CC8. Note also that no DAST and no container scanning run in the framework's pipeline, so neither can be claimed on the strength of this page.
2.6 CC9: Risk Mitigation (Security Scanning)
Control Requirement: The entity identifies, assesses, and manages risks associated with the system.
Framework Implementation:
- SAST (CodeQL)
- No DAST and no container scanning run in this pipeline. If your assessment requires either, you must add it — do not cite it as inherited.
- Secrets scanning (Gitleaks)
- Dependency vulnerability scanning
Consumer Checklist:
- Review security scan results from CI/CD pipeline
- Verify CRITICAL vulnerabilities block deployment
- Document remediation procedures
- Test incident response (tabletop exercises)
Evidence:
- Security scan reports (SARIF, JSON)
- Vulnerability remediation tracking
- Incident response plan
- Tabletop exercise documentation
SSP Statement:
"CC9 is satisfied through comprehensive security scanning in the CI/CD pipeline. Static analysis (CodeQL), secret scanning (Gitleaks), and dependency vulnerability checks run on every build. CRITICAL vulnerabilities block deployment until remediated."
Phase 3: Availability Controls (A1-A3) - Week 4
3.1 A1: Infrastructure Management (Health Checks + Retry Policies)
Control Requirement: The entity maintains, monitors, and evaluates current processing capacity and use of system components.
Framework Implementation:
- Health check endpoints
- Retry policies (Polly)
- Circuit breakers
Consumer Checklist:
- Configure health checks for all dependencies
- Implement retry policies with exponential backoff
Code Example:
// Health checks
services.AddHealthChecks()
.AddSqlServer(connectionString)
.AddRedis(redisConnectionString)
.AddAzureKeyVault(keyVaultUri);
// Retry policies
services.AddHttpClient("ExternalAPI")
.AddPolicyHandler(Policy
.HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
.WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))));
- Test health check failures (simulate dependency outage)
- Test retry policies (verify exponential backoff)
Automated Validation:
// AvailabilityControlValidator automatically checks:
// - Health checks are configured
// - Retry policies are in place
// - Backup configurations exist
- Run
AvailabilityControlValidatorto verify compliance - Review validation results (3 controls: AVL-001, AVL-002, AVL-003)
Evidence:
- Health check configuration
- Retry policy tests
- Uptime monitoring dashboards
SSP Statement:
"A1 is satisfied through comprehensive health checks for all system dependencies. Retry policies with exponential backoff handle transient failures. Circuit breakers prevent cascading failures."
3.2 A2: Capacity Management
Control Requirement: The entity monitors system components and resource utilization to enable the implementation of additional capacity to help meet its objectives.
Framework Implementation:
AvailabilityControlValidatorreports capacity monitoring as control AVL-002IComplianceMetricsis the registration point the validator reads- Registration-based verification only: the validator confirms a metrics provider is registered. It does not read a metric, evaluate a threshold, or observe a scaling event.
- If no
IComplianceMetricsis registered, AVL-002 does not pass — it is reported as an unverified control with the gap named in the evidence. Monitoring performed by a system outside this framework may well satisfy A2, but it requires independent attestation rather than our mark. - This describes the framework as it now stands, and no published version behaves this way yet. Through
10.0.0-alpha.10, AVL-002 reports as satisfied whether or not a metrics provider is registered. If you are generating reports from a released package, see Known issues.
Consumer Checklist:
- Configure auto-scaling (Azure App Service, AWS ECS, Kubernetes HPA)
- Set up capacity monitoring (CPU, memory, network, disk)
- Define scaling thresholds (e.g., scale out at 70% CPU)
- Test scaling under load (load testing with k6, JMeter, Gatling)
Evidence:
- Auto-scaling configuration
- Capacity monitoring dashboards
- Load test results
- Scaling event logs
SSP Statement:
"A2 is satisfied through auto-scaling based on CPU and memory utilization. Azure App Service scales out when CPU exceeds 70% for 5 minutes. Load testing validates scaling behavior under peak load."
3.3 A3: Backup & Recovery
Control Requirement: The entity maintains data backup and recovery procedures to meet its objectives.
Framework Implementation:
AvailabilityControlValidatorvalidates backup infrastructure configuration as control AVL-003IBackupConfigurationProvideris the registration point the validator reads- Configuration-based verification only: the validator confirms that a backup configuration is registered and describes itself as configured. It does not enumerate snapshots, contact a backup provider, or verify that any backup was actually taken.
Consumer Checklist:
- Implement and register a backup configuration provider in DI
- Configure automated backups (SQL Server, Azure Storage, AWS S3)
- Define RPO (Recovery Point Objective) and RTO (Recovery Time Objective)
- Test backup restoration (quarterly recommended)
- Document disaster recovery procedures
Code Example:
// The framework ships the interface, not an implementation — you describe your own backup
// arrangement to the validator.
public sealed class AzureBlobBackupConfiguration : IBackupConfigurationProvider
{
public bool IsBackupConfigured => true;
public string? BackupProviderName => "Azure Blob Storage";
public string ConfigurationDescription =>
"Daily backups to geo-redundant storage with 30-day retention";
}
services.AddSingleton<IBackupConfigurationProvider, AzureBlobBackupConfiguration>();
AvailabilityControlValidator reports AVL-003 as satisfied when an IBackupConfigurationProvider
is registered and returns IsBackupConfigured == true, and it records the provider name and
description as evidence. Those values are supplied by you. A passing AVL-003 evidences that a
backup arrangement has been declared, not that a backup exists or that it can be restored.
Restoration testing remains entirely your control, and an assessor will ask for its results.
If no IBackupConfigurationProvider is registered, AVL-003 does not pass. The declared control is absent
and cannot be verified from inside the framework, so it is reported as an unverified control with the gap
named in the evidence rather than as a green. This is the framework as it now stands: through
10.0.0-alpha.10, AVL-003 reports as satisfied with no provider registered — see
Known issues if you are generating reports from a released package.
Backup verification may well be performed by means this framework cannot observe — that is precisely
the case requiring independent attestation rather than our mark.
Evidence:
- Backup configuration provider registration
- Backup verification logs
- Disaster recovery plan
- Recovery test results
SSP Statement:
"A3 is satisfied through automated daily backups with 30-day retention. SQL Server backups are replicated to geo-redundant storage. RPO is 24 hours, RTO is 4 hours. The framework validates that backup infrastructure configuration is declared via
IBackupConfigurationProvider. Quarterly backup restoration tests verify recoverability."
Phase 4: Processing Integrity Controls (PI1-PI3) - Week 5
4.1 PI1: Input Validation
Control Requirement: Inputs are complete, accurate, and valid for processing.
Framework Implementation:
IInputValidatorinterface- FluentValidation integration
- Automatic validation in pipeline
Consumer Checklist:
- Implement validators for all actions
Code Example:
public class CreateOrderActionValidator : AbstractValidator<CreateOrderAction>
{
public CreateOrderActionValidator()
{
RuleFor(x => x.CustomerId)
.NotEmpty().WithMessage("CustomerId is required");
RuleFor(x => x.Items)
.NotEmpty().WithMessage("Order must contain at least one item");
RuleFor(x => x.Total)
.GreaterThan(0).WithMessage("Total must be positive");
}
}
- Test validation (reject invalid inputs)
- Verify validation errors are logged
Automated Validation:
// ProcessingIntegrityControlValidator automatically checks:
// - Input validation is enabled
// - FluentValidation is configured
- Run
ProcessingIntegrityControlValidatorto verify compliance
Evidence:
- Validator implementations
- Validation test results
- Error logs (invalid input rejections)
SSP Statement:
"PI1 is satisfied through comprehensive input validation using FluentValidation. All commands are validated before processing. Invalid inputs are rejected with descriptive error messages."
4.2 PI2: Processing Accuracy (Outbox Pattern + Idempotency)
Control Requirement: Processing is complete, accurate, and timely.
Framework Implementation:
- Outbox pattern for reliable messaging
- Idempotency keys for duplicate prevention
- Correlation IDs for traceability
Consumer Checklist:
- Configure outbox pattern for all published events
Code Example:
services.AddExcalibur(excalibur => excalibur.AddOutbox(outbox => outbox
.UseSqlServer(sql => sql.ConnectionString(connectionString))
.WithProcessing(processing => processing
.PollingInterval(TimeSpan.FromSeconds(5))
.MaxRetryCount(3)
.BatchSize(100))
.EnableBackgroundProcessing()));
// Idempotency
public class ProcessPaymentCommand : ICommand
{
[IdempotencyKey]
public Guid PaymentId { get; set; } // Duplicate prevention
}
- Test duplicate message handling (verify idempotency)
- Test outbox retry logic
Evidence:
- Outbox configuration
- Idempotency tests
- Correlation ID tracing
SSP Statement:
"PI2 is satisfied through the outbox pattern for reliable message publishing. Idempotency keys prevent duplicate processing. Correlation IDs enable end-to-end traceability."
4.3 PI3: Output Completeness (Event Ordering + Correlation IDs)
Control Requirement: Outputs are complete, accurate, and timely.
Framework Implementation:
- Event ordering guarantees
- Correlation IDs for request tracing
- OpenTelemetry distributed tracing
Consumer Checklist:
- Verify event ordering in integration tests
- Configure correlation ID propagation
- Test end-to-end tracing
Evidence:
- Event ordering tests
- Distributed tracing examples
- Correlation ID propagation verification
SSP Statement:
"PI3 is satisfied through guaranteed event ordering within aggregates. Correlation IDs propagate through all service calls. OpenTelemetry distributed tracing validates end-to-end processing."
Phase 5: Confidentiality Controls (C1-C3) - Week 6
5.1 C1: Data Classification
Control Requirement: Information designated as confidential is identified and classified.
Framework Implementation:
[PersonalData]attribute for personal data[Sensitive]attribute for confidential data- Automatic discovery for data inventory
Consumer Checklist:
- Annotate all confidential fields with
[PersonalData]or[Sensitive]
Code Example:
public class CreditCard
{
public Guid Id { get; set; }
[PersonalData]
[Sensitive]
public string CardNumber { get; set; } // PII + confidential
[PersonalData]
[Sensitive]
public string CVV { get; set; }
public DateTime ExpirationDate { get; set; } // NOT sensitive
}
- Generate data classification report
- Review classification with security team
Automated Validation:
// ConfidentialityControlValidator automatically checks:
// - Data classification is enabled
// - [Sensitive] attributes are used
// - [PersonalData] attributes are used
- Run
ConfidentialityControlValidatorto verify compliance
Evidence:
- Data classification report
- Annotated source code
- Classification review documentation
SSP Statement:
"C1 is satisfied through attribute-based data classification. All confidential fields are annotated with
[PersonalData]or[Sensitive]attributes. Automatic discovery generates a comprehensive data inventory."
5.2 C2: Data Protection (Encryption)
Control Requirement: Procedures exist to protect information designated as confidential from unauthorized access.
Framework Implementation:
- Field-level encryption for
[PersonalData]fields on records that also carry[DataSubjectId], and for[EncryptedField]properties (in every released version[Sensitive]classifies and masks only — see the note below before asserting otherwise) - AES-256-GCM encryption
- Integration with Azure Key Vault / AWS KMS
Consumer Checklist:
- Verify encryption at rest (see CC6 above)
- Test access control (unauthorized users cannot decrypt)
Evidence:
- Encryption verification tests (see CC6)
- Access control tests
SSP Statement:
"C2 is satisfied through field-level encryption using AES-256-GCM.
[PersonalData]fields are encrypted at rest on records that also carry[DataSubjectId], with crypto-shredding registered. (In every released version[Sensitive]drives masking and classification, not encryption — confirm against the version you hold before adopting this wording.) Access control prevents unauthorized decryption."
[Sensitive] and encryption: check the version you holdIn every published version up to and including 10.0.0-alpha.11, [Sensitive] classifies and masks
only — it does not cause encryption at rest. Confirm this against the package you restored rather
than against our source, which describes the main branch.
On the main branch [Sensitive] also selects a property for encryption at rest, under the configured
default key purpose. That change is not in any released version. When a release carries it, this
note will name that version; until it names one, do not assert encryption on the strength of
[Sensitive] alone.
5.3 C3: Data Disposal (Cryptographic Erasure)
Control Requirement: Information designated as confidential is disposed of in accordance with the entity's objectives.
Framework Implementation:
IErasureServicefor GDPR-compliant erasure- Cryptographic erasure (key deletion)
- Erasure certificates as a compliance record, not proof of disposal. The
2.0signature covers the payload in full; the framework ships no verifier for it, and certificates written under format1.0signed only three identity fields — see Known issues
Consumer Checklist:
- Configure erasure service (see GDPR checklist)
- Test erasure workflow (request → execution → certificate)
Evidence:
- Your key-management service's own record of each key deletion (for example, its cloud audit trail). This is the evidence that the control operated: the key is what renders the data irrecoverable.
- Erasure configuration
- Erasure certificates, as an internal record of the request only — not as evidence that the data was disposed of
- Conformance results from the arms you wrapped (
ErasureStoreConformanceTestKit)
The framework does not write erasure events to the audit log. If your assessor expects disposal to appear in the tamper-evident audit trail, you must record it there yourself.
Statement for your report:
"C3 is satisfied through cryptographic erasure. Deleting the encryption keys renders the confidential data irrecoverable. The evidence is the key-management service's record of each key deletion. Each erasure also produces an internal record of the request, the data subject and the completion time."
The certificate is a record, not proof. Its signature (format 2.0) does cover the payload in
full, so the claims on a 2.0 certificate are tamper-evident — but the framework ships no way to
verify that signature, and a signature over a claim is not evidence that the claim is true. What
evidences disposal is your key-management service's record of each key deletion.
Two further points before you cite one in a report:
Verification.Verifiedis weaker than it appears. It isDeletedKeyIds.Count == KeysDeleted, so it readstruewhen both are zero. ReadPayload.Verification.DeletedKeyIdsfor what was actually shown gone, andPayload.Verification.Methods— it reportsNonewhen nothing substantiated the erasure.- Certificates written by earlier versions carry a weaker signature. Format
1.0signed only the request id, the subject hash and the completion instant, so its claims could be altered while the signature still verified. CheckPayload.Version.
Full detail on the Known issues page. Treat the certificate's authority as resting on the custody of your own store, and say so in your report rather than attributing it to cryptography.
Report Generation
Type I Report (Point-in-Time)
When to Use:
- Initial SOC 2 certification
- Quarterly compliance check
- Pre-sales requirements
Consumer Checklist:
- Generate Type I report
Code Example:
var options = new ReportOptions
{
CustomTitle = "Acme Corp - Dispatch Message Processing Platform",
Categories =
[
TrustServicesCategory.Security,
TrustServicesCategory.Availability,
TrustServicesCategory.Confidentiality
]
};
var report = await _complianceService.GenerateTypeIReportAsync(
DateTimeOffset.UtcNow,
options,
cancellationToken);
// Export for auditor (via ISoc2AuditExporter sub-interface)
var exporter = (ISoc2AuditExporter)_complianceService.GetService(typeof(ISoc2AuditExporter))!;
var pdf = await exporter.ExportForAuditorAsync(
ExportFormat.Pdf,
DateTimeOffset.UtcNow.AddMonths(-1),
DateTimeOffset.UtcNow,
cancellationToken);
Excalibur.Compliance exports JSON, CSV, XML, Excel and text on its own. PDF export requires the
separate Excalibur.Compliance.Pdf package, because PDF rendering uses
QuestPDF, whose Community edition is free only for organisations under
USD 1,000,000 total annual gross revenue, measured company-wide. Above that threshold a paid
QuestPDF license is required -- see
https://www.questpdf.com/license/ and pick the tier that applies
to you. Keeping it in its own package means that obligation reaches only consumers who ask for PDFs.
dotnet add package Excalibur.Compliance.Pdf
// Select the QuestPDF license yourself, at startup. Excalibur never assigns
// `QuestPDF.Settings.License`: it is a process-global static, so setting it would silently overwrite
// a Professional or Enterprise license you configured, and would assert Community eligibility on
// your behalf.
QuestPDF.Settings.License = QuestPDF.Infrastructure.LicenseType.Community;
services.AddSoc2Compliance();
services.AddSoc2PdfExport(); // from Excalibur.Compliance.Pdf
Without AddSoc2PdfExport(), ISoc2ReportExporter.GetSupportedFormats() omits ExportFormat.Pdf
and a PDF export request is rejected with a message naming the package to install. With the package
registered but no license configured, QuestPDF itself throws when a PDF export is attempted. In both
cases JSON, CSV, XML, Excel and text export are unaffected.
- Review report sections (management assertion, control design, evidence)
- Export report (JSON, CSV, Excel; PDF with
Excalibur.Compliance.Pdf) - Provide to auditor for Type I assessment
Type II Report (Period Assessment)
When to Use:
- Annual SOC 2 audit
- Operating effectiveness demonstration
- Customer due diligence
Consumer Checklist:
- Generate Type II report (typically 6-12 month period)
Code Example:
var report = await _complianceService.GenerateTypeIIReportAsync(
periodStart: new DateTimeOffset(2025, 1, 1, 0, 0, 0, TimeSpan.Zero),
periodEnd: new DateTimeOffset(2025, 12, 31, 23, 59, 59, TimeSpan.Zero),
options,
cancellationToken);
- Review test results (operating effectiveness over period)
- Document any exceptions or findings
- Provide to auditor for Type II assessment
Consumer Responsibilities
Framework Provides:
- Automated control validation (5 validators: Encryption, Audit, Availability, ProcessingIntegrity, Confidentiality). There is no Privacy validator — selecting
TrustServicesCategory.Privacyenables no automated validation. - Evidence collection from audit logs and system state
- Type I and Type II report generation
- Export formats for auditors (JSON, CSV, Excel, PDF)
Consumer Must Implement:
- Organizational controls (CC1, CC2, CC3)
- Management commitment and ethics policies
- Risk assessment procedures
- Change management approvals
- Backup and disaster recovery testing
- Security awareness training
- Vendor management
- Physical security
Compliance Verification
Pre-Certification Testing
Week 7: Automated Validation
- Run all built-in validators:
EncryptionControlValidator— SEC-001, SEC-002, SEC-003AuditLogControlValidator— SEC-004, SEC-005AvailabilityControlValidator— AVL-001, AVL-002, AVL-003ProcessingIntegrityControlValidator— INT-001, INT-002, INT-003ConfidentialityControlValidator— CNF-001, CNF-002, CNF-003
- Review validation results. Only SEC-001, SEC-003 and SEC-004 can report EFFECTIVE; the other eleven controls are reported unverified by design, because the framework declines to certify a control it cannot observe from inside itself. Expect that, and supply independent attestation for those.
- Document any gaps and remediate
Week 8: Evidence Collection
- Generate Type I report (point-in-time)
- Review evidence completeness:
- Audit logs (sample)
- Encryption configuration
- Access control policies
- Monitoring dashboards
- CI/CD pipeline runs
- Security scan results
- Export evidence package for auditor
Week 9: External Audit Preparation
- Select SOC 2 auditor (CPA firm)
- Schedule kickoff meeting
- Provide system description and scope
- Provide Type I report and evidence
- Respond to auditor questions
- Remediate any findings
Type I Assessment (8-12 weeks)
- Auditor reviews control design
- Auditor tests control implementation
- Auditor issues Type I report (unqualified opinion = success)
Type II Assessment (6-12 months later)
- Operate controls for review period (typically 6-12 months)
- Generate Type II report (period assessment)
- Auditor tests operating effectiveness
- Auditor issues Type II report
Evidence References
Primary Evidence
Framework Implementation:
- Audit logging — SOC 2 controls - Control mapping
- Security guide - Security capabilities
- Audit logging - Audit logging guide
Automated Validation:
- Built-in validators (5 validators, 14 controls)
- Conformance test kits (Audit, Erasure, LegalHold, DataInventory; the count that evidences a control is the one your own run executed)
Evidence Artifacts:
- Audit log samples
- Encryption configuration
- Health check results
- CI/CD pipeline runs (90-day retention)
- Security scan reports (CodeQL SAST, Gitleaks secrets, dependency scanning)
- SBOM artifacts
Supporting Documentation
Standards:
Framework Documentation:
Continuous Compliance
Automated Monitoring
Hourly (Recommended):
- Control validation (all 14 controls)
- Gap detection (severity threshold: Medium)
- Alerting (PagerDuty, Slack, email)
Daily:
- Audit log integrity verification
- Encryption key rotation status
- Health check status
- Backup verification
Weekly:
- Security scan results review
- Vulnerability remediation tracking
- Incident review
Monthly:
- Compliance status report
- Gap remediation review
- Evidence collection
Contact
Questions:
- Product Manager: SOC 2 scope, service commitments
- Software Architect: Technical controls, automation
- Project Manager: Audit coordination, evidence package
Escalation:
- Control failures: See incident response procedures
- Compliance gaps: Create GitHub issue with
compliancelabel - Audit requests: Contact Project Manager for evidence package
See Also
- Compliance Checklists - All compliance checklists overview
- Audit Logging - Tamper-evident audit logging with hash chain integrity
- Security Overview - Security architecture and threat model
Last Updated: 2026-09-12 Document status: every Trust Services criterion in scope is walked through below. This describes the document, not your compliance posture — and note that only 3 of the 14 automated controls can report EFFECTIVE; the rest are reported unverified by design and need independent attestation.