Evidência

A coleta de evidências é um dos aspectos essenciais da arquitetura de referência do DevSecOps. As evidências de conformidades criam a trilha de auditoria utilizada pelos auditores durante uma auditoria de conformidade. Um dos objetivos do DevSecOps é a geração automatizada de evidências e o arquivamento em armazenamentos de evidências auditáveis.

A maneira como os pipelines do DevSecOps lidam com as evidências (formato de arquivo e estrutura de bloqueio) é:

Criação de evidências

As evidências são diferentes dos artefatos criados pelas etapas dos estágios de um pipeline, como resultados de testes de unidades ou arquivos XML ou JSON. Cada tarefa deve se reportar a várias ferramentas responsáveis pelas ações de manipulação de evidências, como criação, formatação e armazenamento de evidências.

Qualquer teste, verificação ou varredura genérica pode produzir evidências dentro de um estágio de pipeline, utilizando as etapas dentro das ferramentas DevSecOps ou os pipelines mostrados na imagem a seguir. As ferramentas do DevSecOps devem ser capazes de receber o resultado da tarefa, criar a evidência e armazená-la no armário de evidências.

Criação de evidência
Criação de evidência

O formato da evidência contém o resultado da tarefa (aprovação ou reprovação), links para os artefatos criados e links para qualquer emissão de incidente que seja criada com base no resultado da tarefa.

Essas ferramentas se concentram apenas na coleta de evidências e não alteram o comportamento do processo de construção. O pipeline de referência de DevSecOps não se rompe em razão de resultados de tarefas com falha. Uma imagem pode ser construída e implementada tendo testes com falha e vulnerabilidades caso haja evidências das verificações e falhas, se a equipe for notificada, se uma solicitação de mudança criada durante a implementação mostrar evidências desses problemas e se a solicitação de mudança for aprovada manualmente.

Fluxo de evidências

O diagrama a seguir mostra como as evidências são tratadas e como elas fluem pelos estágios de integração contínua e implantação contínua.

fluxo de evidências

Fluxo de evidências
Fluxo de evidências

Cada fragmento de evidência coletado nos vários estágios da Arquitetura do DevOps é mantido em armazenamentos de evidências auditáveis, Durante a implementação, essas evidências são coletadas para permitir a criação de um resumo de evidências, que é salvo no armazenamento de evidências, ao final da execução da implementação.

O resumo de evidências é anexado à solicitação de mudança, que é postada para o armazenamento de solicitações de mudanças Durante a aprovação manual de uma solicitação de mudança, o aprovador fica ciente dos problemas encontrados durante a construção.

v2 provas (formato atual)

v2 armário de provas

As evidências são armazenadas em uma hierarquia plana, em que cada evidência é identificada por seu próprio hash SHA256, o que fornece uma camada de proteção de integridade (ou seja, qualquer modificação do conteúdo da evidência pode ser detectada). Como cada evidência está relacionada a um ou mais ativos, os algoritmos de resumo de evidências descobrem as evidências relevantes com base nos ativos.

A única hierarquia é a diferenciação de tipo e algum agrupamento hash semelhante à estrutura de objetos hash Git.

Exemplo

.
└── raw/
    ├── assets/
    │   └── xx/
    │       └── abcdef123456789/
    │           ├── evidences/
    │           │   ├── 00abcdef123456789
    │           │   └── 01abcdef123456789
    │           └── index.json
    ├── attachments/
    │   ├── aa/
    │   │   └── abcdef123456789/
    │   │       └── content
    │   └── ab/
    │       └── abcdef123456789/
    │           └── content
    ├── cd/
    │   ├── c9b77749-fd59-4d32-bbdb-18e55db1615d/
    │          └── summary.json
    |          └── evdience-checks.json
    ├── cc/
    │   ├── absd7749-fd59-4d32-bbdb-18e55db1615d/
    │          └── summary.json
    |          └── evdience-checks.json              
    └── evidences/
        ├── 00/
        │   └── abcdef123456789/
        │       └── index.json
        └── 01 /
            └── abcdef123456789/
                └── index.json      

Coleção de provas v2

As provas do v2 devem ser coletadas o mais próximo possível do processo que criou o resultado para uma prova. Depois de cada varredura executar, após cada teste por exemplo.

Para coletar evidências, o script collect-evidence pode ser usado nos pipelines DevSecOps.

Formato de evidência v2

Uma peça de evidência representa o resultado de uma varredura, teste e assim por diante. As provas estão sempre conectadas a pelo menos um único ativo. Vários ativos são permitidos, como uma única suíte de testes de ponta a ponta que provavelmente testa vários ativos juntos.

Um ativo representa algo que você pode testar, escanear, e assim por diante, como um Git commit em um repositório, ou um docker image, ou qualquer ativo generic com um URI.

Os tipos Evidence e Asset representam o esquema dos elementos do armário v2: evidência e ativo. Embora o esquema use a sintaxe typescript, é possível convertê-lo, para que passe a usar o esquema JSON.

type SHA1 = string;          // 40 character string representing a SHA-1 hash in hexadecimal format
type SHA256 = string;        // 64 character string representing a SHA256 hash in hexadecimal format
type IssueURL = string;      // Link to issues on a git service provide like GitHub or GitLab
type RepositoryURL = string; // Link to a git repository
type AssetURI = string;      // URI of an Asset, like an image or a repository link and git hash
type FileName = string;      // file basename of the attachment


interface Evidence {
  version: 2;
  id: SHA256;
  date: string;
  evidence_type_id: string;
  evidence_type_version: string;
  origin: {
    // scope defines a contextual set for multiple evidence, usually a SHA256 identifier or a CI/CD run ID
    scope: SHA256;  

    // any further IDs can be used to determine evidence origin, see example
    [index: string]: string;
  },
  details: {
    result: 'success' | 'failure' | 'pending';
    tool: string;

    // field "details" can have any arbitrary key-value pairs to provide metadata
    [index: string]: string;
  }
  attachments: Record<string, string> | EvidenceAssetAttachment[];
  assets: string[] | EvidenceAssetAttachment[];
  issues: IssueURL[],
  findings?: IncidentFinding[];
}

export interface IncidentFinding {
  id: string;
  url: string;
  due_date: string;
  first_found?: string;
  severity: ("high", "medium", "low", "critical, "informational");
  has_exempt: boolean;
  found_status: ("new", "existing", "autoclosed", "readonly");
}

export interface EvidenceAssetAttachment {
  url: string; // hash of the asset or attachment
  hash: string; // complete url of the asset or attachment
  uri?: string; // name of the asset
}

interface Asset {
    version: 1;
    id: SHA256;
    uri: AssetURI;
    date: string;
    type: 'commit' | 'image' | 'generic';
    origin: {
      // any IDs can be used to determine asset origin, see example
      [index: string]: string;
    },
    details: Record<string, string>,

    // Assets can relate to each other, for example
    // an Image Asset can relate to the Git Commit Asset
    // it was built from on code level
    related: SHA256[];
}

Exemplo

Exemplo v2 Ativo
{
  "version": "1",
  "id": "cdd3ee20188d2f5bfb7f14bdb9c7fa99b22184ca195d9fa0a953dfbe9b1769cb",
  "uri": "https://github.com/<org-name>/e2e-hello-compliance-app-20220412084808399.git#8c2a65373cb4fd27bccff646e8bdf63d02cae856",
  "origin": {
    "toolchain_crn": "crn:v1:bluemix:public:toolchain:us-south:a/40111714589c4f7099032529b26a7a63:fd3f2bf6-00f1-417f-b1a2-7df894223115::",
    "pipeline_run_id": "a5e89ecc-a413-4dcb-b129-ff870ef3be85",
    "pipeline_id": "66b583d9-3d1b-4b34-9e3a-cb807bf0c5ab"
  },
  "details": {
    "sha": "8c2a65373cb4fd27bccff646e8bdf63d02cae856",
    "repository": "https://github.com/<org-name>/e2e-hello-compliance-app-20220412084808399.git"
  },
  "date": "2022-04-20T09:26:46.226Z",
  "type": "commit",
  "related": [
    "26a0f02126461e6505d5001d50ac71e585c280479a01cc70e36397a784440bf8"
  ]
}
Exemplo v2 provas
{
  "version": "2",
  "id": "3fd209270fbaf46137ec3966affac2a431a835e750301c7c44d583e0e426e29e",
  "date": "2022-04-20T09:33:43.782Z",
  "evidence_type_id": "com.ibm.code_vulnerability_scan",
  "evidence_type_version": "1.0.0",
  "details": {
    "result": "failure",
    "tool": "cra"
  },
  "origin": {
    "toolchain_crn": "crn:v1:bluemix:public:toolchain:us-south:a/779c0808c946b9e15cc2e63013fded8c:68213c68-4794-4d5e-ab50-f33d0d6190e4::",
    "pipeline_id": "c17f18a6-24dd-4949-abb7-2b374f4691b6",
    "pipeline_run_id": "d7a88836-72a1-402b-bb28-701439a543ae",
    "pipeline_run_url": "https://cloud.ibm.com/devops/pipelines/tekton/c17f18a6-24dd-4949-abb7-2b374f4691b6/runs/d7a88836-72a1-402b-bb28-701439a543ae/code-compliance-checks/run-stage/?env_id=ibm:yp:us-south",
    "scope": "117458e26512b0308d93cf6852958e5e875294a982d2b4ea2e9f463b4551a846"
  },
  "assets": [
    {
      "hash": "cdd3ee20188d2f5bfb7f14bdb9c7fa99b22184ca195d9fa0a953dfbe9b1769cb",
      "uri": "https://github.com/<org-name>/e2e-hello-compliance-app-20220412084808399.git#8c2a65373cb4fd27bccff646e8bdf63d02cae856",
      "url": "https://s3.private.us-south.cloud-object-storage.appdomain.cloud/test/assets/cdd3ee20188d2f5bfb7f14bdb9c7fa99b22184ca195d9fa0a953dfbe9b1769cb/index.json"
    }
  ],
  "issues": [
    "https://github.com/<org-name>/e2e-compliance-incident-issues-20220412084808401/issues/1",
    "https://github.com/<org-name>/e2e-compliance-incident-issues-20220412084808401/issues/2",
    "https://github.com/<org-name>/e2e-compliance-incident-issues-20220412084808401/issues/3",
  ],
  "findings": [
    {
      "id": "CVE-2022-42011",
      "due_date": "2024-04-20",
      "severity": "medium",
      "first_found": "2024-03-06",
      "url": "https://github.com/<org-name>/e2e-compliance-incident-issues-20220412084808401/issues/3",
      "found_status": "new",
      "has_exempt": true
    },
    {
      "id": "CVE-2022-42010",
      "due_date": "2024-04-20",
      "severity": "medium",
      "first_found": "2024-03-06",
      "url": "https://github.com/<org-name>/e2e-compliance-incident-issues-20220412084808401/issues/1",
      "found_status": "existing",
      "has_exempt": false
    },
    {
      "id": "CVE-2023-34969",
      "due_date": "2024-04-20",
      "severity": "medium",
      "first_found": "2024-03-06",
      "url": "https://github.com/<org-name>/e2e-compliance-incident-issues-20220412084808401/issues/2",
      "found_status": "existing",
      "has_exempt": true
    }
  ],
  "attachments": [
    {
      "hash": "9a841ef856a5de813dbe440b102b9bff3ca1831630292cff7323c557704f386b",
      "url": "https://s3.private.us-south.cloud-object-storage.appdomain.cloud/test/assets/9a841ef856a5de813dbe440b102b9bff3ca1831630292cff7323c557704f386b/index.json"
    }
  ]
}

Resumo da evidência v2

O pipeline do DevSecOps cria um documento de resumo de evidências. Este documento contém a mais recente de todas as evidências criadas durante cada uma das compilações de integração contínua que implantam uma imagem e as evidências criadas durante a própria implantação. O resumo é criado para a solicitação de mudança que é necessária para implantar qualquer estágio.

interface Summary {
  version: '2.0';                // schema version
  date: string;                  // ISO-8601, UTC, ie. YYYY-MM-DDThh:mm:ssZ
  toolchain_crn: string;         // CRN of the toolchain that generated the summary
  pipeline_id: string;           // ID of the pipeline that generated the summary
  pipeline_run_id: string;       // ID of the pipeline run that generated the summary
  evidences: Evidence[];
}

Este resumo não executa nenhuma agregação de resultado. São os dados brutos das evidências coletadas v2, conforme foram encontradas para os ativos relacionados a uma solicitação de alteração.