Evidence Collection & Retention Policy
Document control
| Field | Value |
|---|---|
| Owner | Ron Benisty — CTO & CSO (ron.b@iontwrks.com) |
| Status | Approved |
| Version | 1.1 |
| Classification | Confidential |
| Approved by | Ron Benisty — CTO & CSO |
| Approval date | 2026-05-26 (Tuesday) |
| Last reviewed | 2026-08-31 |
| Review cycle | Annual — next review due May 2027 |
| Parent policy | Secure SDLC (SSDLC) |
Satisfies the SOC 2 Type II meta-requirement that controls produce sampleable, durable evidence over the audit window; supports ISO/IEC 27001:2022 A.5.33 (protection of records) and A.8.15 (logging); supports SOC 2 CC4.1–CC4.2 (monitoring). Closes Gap 4 of the SSDLC gap analysis.
1. Purpose
A control that operates without leaving a durable artifact is invisible to Type II testing. This policy ensures every recurring SSDLC control emits a timestamped, tamper-evident record, that the records are retained for the audit window, and that the population of records is sampleable on demand.
2. Scope
Every SSDLC control listed in the SSDLC umbrella policy and its sibling policies. New controls added to the SSDLC must declare their evidence artifact and retention in this register before they are considered "in place."
3. The Evidence Register
The single source of truth — every recurring control, its artifact, its source system, its owner, and its retention.
| Control | Artifact | Source system | Owner | Retention |
|---|---|---|---|---|
| Change management | Merged PR (description + CODEOWNER approvals + CI run + deploy log) | GitHub + GitHub Actions | CTO & CSO | ≥ 12 months |
| Separation of duties | PR approvals (author ≠ approver), deployment approvals | GitHub | CTO & CSO | ≥ 12 months |
| Build & pipeline integrity | SBOMs (Syft, cyclonedx-npm), scan reports (TruffleHog, OSV-Scanner, Trivy, Semgrep), Harden-Runner logs, cosign signatures, OpenSSF Scorecard history | GitHub Actions | CTO & CSO | ≥ 12 months |
| Access reviews | Signed monthly + quarterly + annual records | GitHub + AWS IAM + WorkOS + Logz.io + Cloudflare | CTO & CSO | ≥ 12 months |
| Vulnerability management | Scan results + remediation tracked against SLA | OSV-Scanner / Trivy / Dependabot / GuardDuty / Logz.io | CTO & CSO | ≥ 12 months |
| Penetration testing | Annual pen-test report + remediation evidence | External vendor + internal tracker | CTO & CSO | ≥ 24 months |
| Backup verification | Weekly RDS restore-test log; monthly S3 integrity-check log; annual DR-drill report | AWS Backup + Terraform deploy runbook | CTO & CSO | ≥ 12 months |
| Incident response | Incident record per incident + post-incident review + quarterly drill log | Internal tracker + Logz.io | CTO & CSO | ≥ 24 months |
| Root-cause analysis | RCA write-up per Sev 1 / Sev 2 + recurring-class triggers | Internal tracker | CTO & CSO | ≥ 24 months |
| Customer activity & audit | Per-tenant audit_events table (append-only) | Tenant Postgres schema | Tenant + S.E.T | 7 years |
| AWS API activity | CloudTrail multi-region trail | S3 with Object Lock | CTO & CSO | 7 years |
| Network audit | VPC Flow Logs | CloudWatch → S3 Glacier | CTO & CSO | 30 d hot, 1 y cold |
| Internal operational logs | Application logs, traces, frontend errors | Logz.io | CTO & CSO | 30 days hot; archive → S3 Glacier 7 years |
| Cross-tenant isolation testing | CI test run per PR | GitHub Actions | CTO & CSO | ≥ 12 months |
| Developer security training | Completion records per developer per cycle | Training provider (TBD — SSDLC Gap 11) | CTO & CSO | ≥ 24 months |
| Supplier / dev-firm review | Monthly GitHub audit-log review + quarterly collaborator reconciliation + annual right-to-audit record | GitHub + internal log | CTO & CSO | ≥ 12 months |
| Risk assessment | Annual full-assessment memo + quarterly review records + on-major-change trigger memos + the Risk Register itself (Risk Assessment Policy) | Repo (docs/risk-register.md + docs/risk-reviews/) | CTO & CSO | ≥ 24 months (memos); lifetime (register) |
| Tenant decommissioning | Deletion certificate per tenant | Internal log | CTO & CSO | 7 years |
| Policy approvals & reviews | Policy document + annual-review record per policy | This repository (docs/s-e-t/ssdlc-policies/**) | CTO & CSO | Lifetime of the policy + 7 years |
Retention floors: SOC 2 Type II requires ≥ 12 months (covering one full audit window). Incident, RCA, training, pen-test, and risk-assessment records are extended to 24 months (they typically span multiple windows). Tamper-evident regulatory records (CloudTrail, customer audit, deletion certificates) sit at 7 years. All matches the retention discipline in Supply Chain & CI/CD Security and Observability & Logging.
4. Tamper-evidence
- Append-only writes for customer audit (Observability §Tier 1) —
DELETE/UPDATErevoked at the DB role level. - S3 Object Lock (Compliance mode) on CloudTrail archive, Backup bucket, and Evidence bucket — once written, cannot be deleted within the retention period even by AWS root.
- GitHub commit + PR history — append-only by design; force-push blocked on protected branches.
- cosign signatures — provenance trail for every released container image.
5. Quarterly evidence-completeness review
Every quarter the CTO & CSO inspects a sample from each row of §3 against the audit window, confirms each artifact is retrievable, and signs a one-page completeness record. Findings (missing artifacts, broken pipelines, unexpected retention gaps) become PR-tracked remediation items per the Change Management Policy.
6. Access to evidence
- Read access to the evidence register and source systems is restricted to the CTO & CSO and authorized auditors.
- External auditors are granted scoped, time-bounded, read-only access per the Audit Testing Scope Policy.
- All access to evidence is itself logged (CloudTrail + GitHub audit log + Logz.io).
7. Onboarding new controls
When a new SSDLC control is introduced, the policy that defines it must:
- Add a row to §3 (artifact + source system + owner + retention).
- Confirm the source system already produces the artifact, or define how it will.
- Set the retention to ≥ 12 months (or higher per category).
- Be approved by the CTO & CSO before the control is marked "in place" in the SSDLC umbrella.
8. Evidence Archive — deployed implementation (CI logs & artifacts)
Status: In place (deployed 2026-08). This is the concrete, running realisation of the "immutable store" referenced in Supply Chain & CI/CD Security §evidence retention and the S3 Object Lock (Compliance) control in §4 above. GitHub retains Actions logs for only 90 days on the Team plan; this pipeline copies each run's logs + artifacts into a write-once, read-many (WORM) bucket so the evidence outlives that window.
8.1 Where it lives
| Property | Value |
|---|---|
| AWS account | 429134227608 (scanners-prod) |
| Region | eu-north-1 (Stockholm) |
| Evidence bucket | s3://iontwrks-ci-evidence |
| Object Lock | COMPLIANCE mode, default retention 400 days (≥ SOC 2's 12-month floor; raise to 2555 for a 7-year class) — no one, not even AWS root, can delete or alter an object before it expires |
| Encryption | SSE-KMS (bucket-key enabled) |
| Versioning | Enabled (required for Object Lock) |
| Public access | Fully blocked (all four BPA flags) |
| Cost control | Lifecycle → Glacier Deep Archive after 90 days (still WORM-locked) |
| Write role | arn:aws:iam::429134227608:role/gha-log-archive — GitHub-OIDC, write-only (s3:PutObject + s3:ListBucket), max session 1 h. Cannot read or delete. |
| IaC | set-platform/infra/log-archive/ (Terraform) |
8.2 What is archived, and from where
.github/workflows/log-archive.yml (present in every covered repo) fires on
workflow_run completion of the Security workflow (and, in set-platform, its
deploy/DAST/Scorecard workflows). It assumes the OIDC role for a short-lived credential
and writes to s3://iontwrks-ci-evidence/<repo>/<workflow>/<run_id>/:
run-logs.zip— full CI logs, including all scanner output (TruffleHog / OSV / Trivy / Semgrep) and Harden-Runner egress detail.artifacts/— SBOMs (CycloneDX/Syft), DAST reports, OpenSSF Scorecard, cosign attestations.metadata.json— repo, run id, workflow, conclusion.
Covered repositories (6): set-platform, set-app, scanners,
reg13-collector-module, Documents, binarynetworks-website. The archive job is
inert until AWS_LOG_ARCHIVE_ROLE_ARN is set on the repo, so it is safe by default.
8.3 Data flow
8.4 Trust boundary (who may write)
The role's trust policy admits only these repos' Actions by OIDC sub. Newer repos
(reg13-collector-module, set-app) emit GitHub's immutable-ID subject form
(repo:IONTWRKS@<org-id>/<repo>@<repo-id>) instead of the plain repo:IONTWRKS/<name>
form, so the trust pins those unforgeable numeric IDs as well — an attacker cannot
spoof an org/repo name to assume the role.
8.5 Manual quarterly control (Team-plan limitation)
The GitHub audit log (who did what / access / settings changes) cannot be automated
on the Team plan (its REST API + streaming are Enterprise-only). Each quarter the CTO & CSO
exports it (Org → Settings → Logs → Audit log → Export → JSON) and uploads it to
s3://iontwrks-ci-evidence/_audit-log/<YYYY-Qn>.json. This is a documented SOC 2 control
row folded into the §5 quarterly completeness review.
8.6 Retrieval
aws s3 cp s3://iontwrks-ci-evidence/<path> . then unzip/grep. For SQL search across the
whole archive, point Athena at the bucket (optional, pay-per-query) — no standing infra.
9. Document change history
| Version | Date | Author | Description of change | Approved by |
|---|---|---|---|---|
| 1.0 | 2026-05-26 | Ron Benisty (CTO & CSO) | Initial version — establishes the Evidence Collection & Retention Policy and the SSDLC evidence register. | Ron Benisty (CTO & CSO) |
| 1.1 | 2026-08-31 | Ron Benisty (CTO & CSO) | Added §8 — the deployed Evidence Archive implementation (WORM S3 iontwrks-ci-evidence in eu-north-1, gha-log-archive OIDC role, log-archive.yml pipeline, 6 covered repos, immutable-ID trust) with data-flow and trust-boundary diagrams. | Ron Benisty (CTO & CSO) |