Implement SOC 2 controls through engineering practices rather than manual processes. Covers Trust Service Criteria, evidence collection automation, continuous compliance monitoring, audit preparation, and the engineering patterns that make compliance sustainable.
SOC 2 Compliance Engineering is the practice of designing, implementing, and maintaining systems that continuously satisfy the Trust Services Criteria—Security, Availability, Processing Integrity, Confidentiality, and Privacy—required for a SOC 2 report. This work matters when an organization must prove its controls are operating effectively over time, especially during audits, and when customers demand evidence of trust in their data handling. It is not a one-off setup but a living system that evolves with infrastructure, policies, and personnel.
The foundation of SOC 2 engineering is mapping control objectives to the five Trust Services Criteria. Each criterion must be implemented as a repeatable, verifiable, and measurable process. The design phase centers on defining how systems collect, store, and report evidence of control effectiveness.
For example, a Security control requires that all systems enforce multi-factor authentication (MFA) for privileged users. This is not just a policy document; it is a system that logs every MFA enrollment, login, and failure. The system must record:
This data is stored in a control_evidence table:
CREATE TABLE control_evidence (
id UUID PRIMARY KEY,
control_id TEXT NOT NULL,
criterion TEXT NOT NULL, -- 'Security', 'Availability', etc.
subject TEXT NOT NULL, -- 'User', 'System', 'Database'
evidence_type TEXT NOT NULL, -- 'log', 'check', 'report'
recorded_at TIMESTAMPTZ NOT NULL,
payload JSONB NOT NULL,
validated_at TIMESTAMPTZ,
validated_by TEXT,
validation_status TEXT CHECK (validation_status IN ('pending', 'passed', 'failed'))
);
Each control is assigned a unique control_id derived from a standardized naming scheme: SEC-01, AVAIL-03, PI-07, etc. These IDs are used in all downstream reports and evidence repositories.
Once controls are designed, they must be validated continuously. This is achieved through automated validation pipelines that run at scheduled intervals and on event triggers.
A typical pipeline uses cron jobs and systemd services, driven by a configuration file in /etc/soc2-engineering/pipeline.yaml:
pipelines:
- name: "mfa-enrollment-validation"
schedule: "*/15 * * * *" # every 15 minutes
triggers:
- event: "user.created"
- event: "mfa.enrolled"
steps:
- type: "sql-query"
name: "check-mfa-enrollments"
query: |
SELECT user_id, COUNT(*) AS enrollments
FROM mfa_enrollments
WHERE created_at > NOW() - INTERVAL '1 hour'
GROUP BY user_id
HAVING COUNT(*) >= 1
expected: "all users have at least one enrollment"
failure_action: "send-alert"
- type: "http-call"
name: "verify-mfa-availability"
url: "https://auth.example.com/api/v1/health"
method: "GET"
expected_status: 200
expected_body: { status: "healthy" }
timeout: 5000
- type: "write-evidence"
name: "record-validation-result"
table: "control_evidence"
data:
control_id: "SEC-01"
criterion: "Security"
subject: "User MFA Enrollment"
evidence_type: "validation-run"
recorded_at: "{{ now }}"
payload:
pipeline_run_id: "{{ pipeline_run_id }}"
results: "{{ step_results }}"
duration_ms: "{{ total_duration }}"
This configuration is consumed by a daemon process, soc2-validator, which executes the pipeline and writes outcomes to the control_evidence table. If any step fails, the pipeline emits a structured log entry:
{
"pipeline_run_id": "8e6b3f12-4a3c-11ef-92f9-0242ac130002",
"started_at": "2024-04-10T12:00:00Z",
"completed_at": "2024-04-10T12:00:47Z",
"status": "failed",
"steps": [
{
"name": "check-mfa-enrollments",
"status": "failed",
"error": "Query returned 4 rows, expected 10",
"duration_ms": 1200,
"output": [
{ "user_id": "u-102", "enrollments": 1 },
{ "user_id": "u-103", "enrollments": 0 },
{ "user_id": "u-104", "enrollments": 2 },
{ "user_id": "u-105", "enrollments": 3 }
]
},
{
"name": "verify-mfa-availability",
"status": "passed",
"duration_ms": 320,
"response": {
"status": 200,
"body": { "status": "healthy" }
}
}
]
}
The soc2-validator process runs as a systemd service:
sudo systemctl enable soc2-validator.service
sudo systemctl start soc2-validator
sudo systemctl status soc2-validator.service
A critical control is Access Control—ensuring only authorized users can access systems. This is implemented using a centralized identity provider (IdP), which emits audit events on login, role assignment, and access revocation.
Events are published via a message queue (e.g., Kafka or RabbitMQ) with the following structure:
{
"event_id": "evt-7a2f5e1b-3c4d-5e6f-7a8b-9c1d2e3f4a5b",
"event_type": "access.role.assigned",
"timestamp": "2024-04-10T11:58:32Z",
"payload": {
"user_id": "u-102",
"role": "admin",
"scope": "project-frontend",
"assigned_by": "u-101",
"reason": "onboarding"
}
}
A consumer service, soc2-access-monitor, subscribes to the event stream and validates that:
This is validated via a check-access-roles SQL query run every 10 minutes:
SELECT
user_id,
role,
COUNT(*) AS total_assignments,
MAX(assigned_at) AS latest_assignment,
MIN(assigned_at) AS first_assignment
FROM access_assignments
WHERE assigned_at > NOW() - INTERVAL '1 hour'
GROUP BY user_id, role
HAVING COUNT(*) >= 1
AND MAX(assigned_at) - MIN(assigned_at) <= INTERVAL '15 minutes';
If the result set is incomplete or delayed, the system logs a validation_error and triggers an alert.
Evidence must be stored in a structured, versioned, and queryable repository. The preferred format is a versioned file store with metadata.
Each evidence item is a file in a directory hierarchy:
/evidence/
├── Security/
│ ├── SEC-01/
│ │ ├── 2024-04-10T12:00:00Z.json
│ │ ├── 2024-04-10T12:15:00Z.json
│ │ └── 2024-04-10T12:30:00Z.json
├── Availability/
│ └── AVAIL-03/
│ ├── 2024-04-10T12:00:00Z.json
│ └── 2024-04-10T12:15:00Z.json
└── Processing Integrity/
└── PI-07/
└── 2024-04-10T12:00:00Z.json
Each file contains the validation result, metadata, and references to original data:
{
"version": "1.0",
"control_id": "PI-07",
"criterion": "Processing Integrity",
"subject": "Order Processing Pipeline",
"evidence_type": "end-to-end-validation",
"collected_at": "2024-04-10T12:00:00Z",
"duration_ms": 12400,
"result": {
"passed": true,
"details": [
{
"step": "data-ingestion",
"status": "success",
"duration_ms": 1400,
"input_count": 1247,
"output_count": 1247,
"error_count": 0
},
{
"step": "transformation",
"status": "failed",
"duration_ms": 3200,
"input_count": 1247,
"output_count": 1221,
"error_count": 26,
"errors": [
"missing_payment_id",
"invalid_customer_code",
"missing_address"
]
}
]
},
"references": [
"https://api.example.com/logs/12345",
"https://s3.amazonaws.com/evidence/2024-04-10T12:00:00Z.json"
],
"generated_by": "[email protected]"
}
Evidence is versioned using git or a simple version.json file in each directory:
{
"current": "2024-04-10T12:00:00Z",
"history": [
"2024-04-10T12:00:00Z",
"2024-04-10T12:15:00Z",
"2024-04-10T12:30:00Z"
]
}
An audit trail is a chronological record of all actions related to a control. It must be immutable, tamper-evident, and queryable.
The audit trail is generated by a service that watches the control_evidence table for new entries and writes them to a audit_trail table:
CREATE TABLE audit_trail (
id UUID PRIMARY KEY,
control_id TEXT NOT NULL,
criterion TEXT NOT NULL,
timestamp TIMESTAMPTZ NOT NULL,
event_type TEXT NOT NULL, -- 'validation-run', 'evidence-created', 'control-changed'
details JSONB NOT NULL,
source_system TEXT,
signature BYTEA,
validated_by TEXT
);
Each audit event is signed using a cryptographic hash:
curl -X POST https://audit.example.com/api/v1/trail \
-H "Content-Type: application/json" \
-d '{
"control_id": "SEC-01",
"criterion": "Security",
"event_type": "validation-run",
"timestamp": "2024-04-10T12:00:00Z",
"details": {
"pipeline_run_id": "8e6b3f12-4a3c-11ef-92f9-0242ac130002",
"status": "passed",
"duration_ms": 47000
},
"source_system": "soc2-validator"
}'
The response includes a signature field:
{
"id": "evt-9a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"signature": "7b9c8d7a6b5c4d3e2f1a0b9c8d7a6b5c4d3e2f1a0b9c8d7a6b5c4d3e2f1a0b9c",
"timestamp": "2024-04-10T12:00:00Z"
}
The signature is computed using HMAC-SHA256 with a secret key stored in secrets/soc2-audit-signing.key. The audit trail is exposed via a simple REST API with pagination and filtering:
curl "https://audit.example.com/api/v1/trail?criterion=Security&from=2024-04-10T12:00:00Z&to=2024-04-10T13:00:00Z"
A control is considered failed when its validation result is failed or pending for more than 30 minutes. The system triggers a remediation workflow:
control_evidence table for the last 3 hours of validation runs.{
"title": "SOC 2 Failure: SEC-01 - MFA Enrollment Validation",
"body": "The validation pipeline for SEC-01 failed on 2024-04-10T12:00:00Z.\n\n- Status: failed\n- Duration: 47 seconds\n- Step failures:\n - check-mfa-enrollments: 4 users missing enrollment\n - verify-mfa-availability: HTTP 503 on auth service\n\nSee evidence at: https://evidence.example.com/Security/SEC-01/2024-04-10T12:00:00Z.json\n\nAction required: investigate auth service and re-run validation.",
"labels": [
"soc2",
"security",
"failure",
"remediation"
],
"assignees": [
"devops-team",
"security-engineers"
]
}
The remediation task is automatically created via curl:
curl -X POST https://jira.example.com/rest/api/2/issue \
-H "Authorization: Bearer $JIRA_TOKEN" \
-H "Content-Type: application/json" \
-d @remediation-ticket.json
Once the task is completed, the control is marked as validated and the audit_trail is updated with a remediation.completed event.
The compliance system must report on the health of all controls. This is done through a dashboard that aggregates:
This is achieved via a soc2-reporter service that runs every hour and generates a report table:
CREATE TABLE report (
id UUID PRIMARY KEY,
report_type TEXT NOT NULL, -- 'daily', 'weekly', 'monthly'
generated_at TIMESTAMPTZ NOT NULL,
data JSONB NOT NULL,
metadata JSONB
);
The report is stored and served via a simple HTTP API:
curl https://report.example.com/api/v1/reports/daily/2024-04-10
Response:
{
"report_id": "rep-1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"report_type": "daily",
"generated_at": "2024-04-10T12:00:00Z",
"summary": {
"total_controls": 24,
"passing": 21,
"failing": 3,
"pending": 2,
"avg_time_to_validation": "34.2s",
"last_evidence_age": "1h 12m"
},
"details": {
"by_criterion": {
"Security": { "total": 8, "passing": 7, "failing": 1 },
"Availability": { "total": 6, "passing": 6, "failing": 0 },
"Processing Integrity": { "total": 5, "passing": 3, "failing": 2 }
},
"top_failing_controls": [
{
"control_id": "SEC-01",
"criterion": "Security",
"failure_reason": "MFA enrollment count mismatch",
"last_run": "2024-04-10T12:00:00Z",
"run_id": "8e6b3f12-4a3c-11ef-92f9-0242ac130002"
}
]
}
}
This report is the core of the SOC 2 compliance artifact, used for audits, internal reviews, and customer onboarding.
This page was rewritten on 18 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.
We use cookies for analytics (Google Analytics) and advertising (Google AdSense) to improve your experience and support free content. Privacy Policy