731 lines
22 KiB
Markdown
731 lines
22 KiB
Markdown
# CI/CD Gate Flow
|
|
|
|
## Overview
|
|
|
|
The CI/CD Gate Flow describes how StellaOps integrates into continuous integration and deployment pipelines to provide automated security gates. The flow covers CLI-based scanning, policy evaluation, and pass/fail decisions that control pipeline progression.
|
|
|
|
**Business Value**: Shift-left security by catching vulnerabilities before deployment, with deterministic, reproducible verdicts that integrate into existing DevOps workflows.
|
|
|
|
## Actors
|
|
|
|
| Actor | Type | Role |
|
|
|-------|------|------|
|
|
| CI Pipeline | System | GitHub Actions, GitLab CI, Jenkins, etc. |
|
|
| StellaOps CLI | Tool | Executes scans from pipeline |
|
|
| Gateway | Service | API entry point |
|
|
| Scanner | Service | Performs image analysis |
|
|
| Policy Engine | Service | Evaluates security policies |
|
|
| Attestor | Service | Signs scan results |
|
|
|
|
## Prerequisites
|
|
|
|
- StellaOps CLI installed in CI environment
|
|
- API credentials configured (token or OIDC)
|
|
- Policy set defined for the pipeline
|
|
- Container image built and available
|
|
|
|
## Supported CI/CD Platforms
|
|
|
|
| Platform | Integration Method | Credentials |
|
|
|----------|-------------------|-------------|
|
|
| GitHub Actions | Action + CLI | OIDC or PAT |
|
|
| GitLab CI | Job template + CLI | CI_JOB_TOKEN or PAT |
|
|
| Azure DevOps | Task + CLI | Service connection |
|
|
| Jenkins | Plugin + CLI | Credentials binding |
|
|
| CircleCI | Orb + CLI | Context variables |
|
|
| Tekton | Task + CLI | Kubernetes secrets |
|
|
|
|
## Flow Diagram
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────────────┐
|
|
│ CI/CD Gate Flow │
|
|
└─────────────────────────────────────────────────────────────────────────────────┘
|
|
|
|
┌────────────┐ ┌───────────┐ ┌─────────┐ ┌─────────┐ ┌────────┐ ┌─────────┐
|
|
│ CI Pipeline│ │StellaOps │ │ Gateway │ │ Scanner │ │ Policy │ │ Attestor│
|
|
│ │ │ CLI │ │ │ │ │ │ │ │ │
|
|
└─────┬──────┘ └─────┬─────┘ └────┬────┘ └────┬────┘ └───┬────┘ └────┬────┘
|
|
│ │ │ │ │ │
|
|
│ docker build │ │ │ │ │
|
|
│───────┐ │ │ │ │ │
|
|
│ │ │ │ │ │ │
|
|
│<──────┘ │ │ │ │ │
|
|
│ │ │ │ │ │
|
|
│ stellaops │ │ │ │ │
|
|
│ scan │ │ │ │ │
|
|
│ --policy=prod │ │ │ │ │
|
|
│──────────────>│ │ │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ POST /scans │ │ │ │
|
|
│ │────────────>│ │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ Dispatch │ │ │
|
|
│ │ │───────────>│ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ │ Analyze │ │
|
|
│ │ │ │ image │ │
|
|
│ │ │ │───┐ │ │
|
|
│ │ │ │ │ │ │
|
|
│ │ │ │<──┘ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ │ Evaluate │ │
|
|
│ │ │ │──────────>│ │
|
|
│ │ │ │ │ │
|
|
│ │ │ │ │ Apply │
|
|
│ │ │ │ │ rules │
|
|
│ │ │ │ │───┐ │
|
|
│ │ │ │ │ │ │
|
|
│ │ │ │ │<──┘ │
|
|
│ │ │ │ │ │
|
|
│ │ │ │ Verdict │ │
|
|
│ │ │ │<──────────│ │
|
|
│ │ │ │ │ │
|
|
│ │ │ │ Sign │ │
|
|
│ │ │ │──────────────────────>│
|
|
│ │ │ │ │ │
|
|
│ │ │ │ DSSE │ │
|
|
│ │ │ │<──────────────────────│
|
|
│ │ │ │ │ │
|
|
│ │ │ Result │ │ │
|
|
│ │ │<───────────│ │ │
|
|
│ │ │ │ │ │
|
|
│ │ Verdict │ │ │ │
|
|
│ │<────────────│ │ │ │
|
|
│ │ │ │ │ │
|
|
│ Exit code │ │ │ │ │
|
|
│ (0=pass, │ │ │ │ │
|
|
│ 1=fail) │ │ │ │ │
|
|
│<──────────────│ │ │ │ │
|
|
│ │ │ │ │ │
|
|
│ [if pass] │ │ │ │ │
|
|
│ docker push │ │ │ │ │
|
|
│───────┐ │ │ │ │ │
|
|
│ │ │ │ │ │ │
|
|
│<──────┘ │ │ │ │ │
|
|
│ │ │ │ │ │
|
|
```
|
|
|
|
## Step-by-Step
|
|
|
|
### 1. Pipeline Configuration
|
|
|
|
#### GitHub Actions Example
|
|
|
|
```yaml
|
|
name: Build and Scan
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
branches: [main]
|
|
|
|
jobs:
|
|
build-and-scan:
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
id-token: write # For OIDC
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Build Docker image
|
|
run: |
|
|
docker build -t myapp:${{ github.sha }} .
|
|
|
|
- name: Install StellaOps CLI
|
|
run: |
|
|
curl -sSL https://get.stellaops.io/cli | sh
|
|
echo "$HOME/.stellaops/bin" >> $GITHUB_PATH
|
|
|
|
- name: Authenticate with OIDC
|
|
run: |
|
|
stellaops auth login --oidc \
|
|
--issuer ${{ secrets.STELLAOPS_OIDC_ISSUER }} \
|
|
--client-id ${{ secrets.STELLAOPS_CLIENT_ID }}
|
|
|
|
- name: Scan image
|
|
id: scan
|
|
run: |
|
|
stellaops scan myapp:${{ github.sha }} \
|
|
--policy production \
|
|
--format sarif \
|
|
--output results.sarif \
|
|
--attestation \
|
|
--fail-on violation
|
|
|
|
- name: Upload SARIF to GitHub Security
|
|
if: always()
|
|
uses: github/codeql-action/upload-sarif@v2
|
|
with:
|
|
sarif_file: results.sarif
|
|
|
|
- name: Push to registry
|
|
if: steps.scan.outcome == 'success'
|
|
run: |
|
|
docker tag myapp:${{ github.sha }} ghcr.io/org/myapp:${{ github.sha }}
|
|
docker push ghcr.io/org/myapp:${{ github.sha }}
|
|
```
|
|
|
|
#### GitLab CI Example
|
|
|
|
```yaml
|
|
stages:
|
|
- build
|
|
- scan
|
|
- deploy
|
|
|
|
variables:
|
|
STELLAOPS_API_URL: https://api.stellaops.local
|
|
|
|
build:
|
|
stage: build
|
|
script:
|
|
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
|
|
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
|
|
|
scan:
|
|
stage: scan
|
|
image: stellaops/cli:latest
|
|
script:
|
|
- stellaops auth login --token $STELLAOPS_TOKEN
|
|
- stellaops scan $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
|
--policy production
|
|
--fail-on violation
|
|
artifacts:
|
|
reports:
|
|
sast: gl-sast-report.json
|
|
|
|
deploy:
|
|
stage: deploy
|
|
needs: [scan]
|
|
script:
|
|
- kubectl set image deployment/myapp app=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
|
```
|
|
|
|
### 2. CLI Authentication
|
|
|
|
The CLI supports multiple authentication methods:
|
|
|
|
| Method | Command | Use Case |
|
|
|--------|---------|----------|
|
|
| Token | `stellaops auth login --token $TOKEN` | CI/CD with secrets |
|
|
| OIDC | `stellaops auth login --oidc` | GitHub/GitLab OIDC |
|
|
| Interactive | `stellaops auth login` | Local development |
|
|
| Keyless | `stellaops auth login --keyless` | Sigstore OIDC |
|
|
|
|
### 3. Scan Execution
|
|
|
|
CLI submits scan request and waits for completion:
|
|
|
|
```bash
|
|
stellaops scan docker.io/myorg/myapp:v1.2.3 \
|
|
--policy production \
|
|
--format json \
|
|
--output scan-results.json \
|
|
--attestation \
|
|
--timeout 5m \
|
|
--fail-on violation
|
|
```
|
|
|
|
#### CLI Options
|
|
|
|
| Option | Description | Default |
|
|
|--------|-------------|---------|
|
|
| `--policy` | Policy set to evaluate against | `default` |
|
|
| `--format` | Output format (json, sarif, table) | `table` |
|
|
| `--output` | Write results to file | stdout |
|
|
| `--attestation` | Generate DSSE attestation | false |
|
|
| `--timeout` | Maximum wait time | 10m |
|
|
| `--fail-on` | Exit 1 on: `violation`, `warning`, `any` | `violation` |
|
|
| `--quiet` | Suppress progress output | false |
|
|
|
|
### 3b. AI Code Guard (optional)
|
|
|
|
Run AI code guard checks on a change set and emit CI-friendly output:
|
|
|
|
```bash
|
|
stella guard run \
|
|
--policy .stellaops.yml \
|
|
--format sarif \
|
|
--out guard.sarif
|
|
```
|
|
|
|
Recommended exit behavior:
|
|
- pass: exit 0
|
|
- review: exit 0 (with warning in report)
|
|
- block: exit 1
|
|
|
|
### 4. Policy Evaluation
|
|
|
|
Policy engine evaluates findings against CI-specific rules:
|
|
|
|
```yaml
|
|
# Policy Set: production
|
|
version: "stella-dsl@1"
|
|
name: production
|
|
|
|
rules:
|
|
- name: block-critical
|
|
condition: severity == 'critical' AND vex_status != 'not_affected'
|
|
action: FAIL
|
|
|
|
- name: block-high-unfixed
|
|
condition: severity == 'high' AND fixed_version == null
|
|
action: FAIL
|
|
|
|
- name: block-known-exploited
|
|
condition: kev == true
|
|
action: FAIL
|
|
|
|
- name: require-sbom
|
|
condition: sbom_complete == false
|
|
action: FAIL
|
|
message: "SBOM must cover all detected packages"
|
|
|
|
gates:
|
|
ci:
|
|
max_critical: 0
|
|
max_high_unfixed: 0
|
|
require_attestation: true
|
|
```
|
|
|
|
### 5. Verdict and Exit Code
|
|
|
|
CLI translates verdict to exit code:
|
|
|
|
| Verdict | Exit Code | Pipeline Result |
|
|
|---------|-----------|-----------------|
|
|
| PASS | 0 | Continue |
|
|
| WARN | 0 (or 1 if `--fail-on warning`) | Continue with warning |
|
|
| FAIL | 1 | Block deployment |
|
|
| ERROR | 2 | Pipeline failure |
|
|
|
|
### 5a. DSSE Witness Verification (Required)
|
|
|
|
> Sprint: SPRINT_20260112_004_DOC_cicd_gate_verification
|
|
|
|
Before deploying, pipelines must verify DSSE witness signatures and Rekor inclusion (or offline ledger). This ensures attestation integrity and provides tamper-evident audit trail.
|
|
|
|
#### Online Verification
|
|
|
|
```bash
|
|
# Verify DSSE signature and Rekor inclusion
|
|
stellaops proof verify \
|
|
--image ghcr.io/org/myapp:$COMMIT_SHA \
|
|
--attestation-type scan-result \
|
|
--check-rekor \
|
|
--fail-on-missing
|
|
|
|
# Exit codes:
|
|
# 0 - Verified successfully
|
|
# 1 - Verification failed
|
|
# 2 - Missing attestation or Rekor entry
|
|
```
|
|
|
|
#### Offline Verification (Air-Gapped Environments)
|
|
|
|
```bash
|
|
# Verify against local offline ledger
|
|
stellaops proof verify \
|
|
--image myapp:$COMMIT_SHA \
|
|
--attestation-type scan-result \
|
|
--offline \
|
|
--ledger-path /var/lib/stellaops/ledger \
|
|
--fail-on-missing
|
|
|
|
# Alternative: verify a bundled evidence pack
|
|
stellaops evidence-pack verify \
|
|
--bundle /path/to/evidence-pack.tar.gz \
|
|
--check-signatures \
|
|
--check-merkle
|
|
```
|
|
|
|
#### Cosign Equivalent Commands
|
|
|
|
For environments using cosign directly:
|
|
|
|
```bash
|
|
# Online: verify with Rekor
|
|
cosign verify-attestation \
|
|
--type https://stellaops.io/attestation/scan/v1 \
|
|
--rekor-url https://rekor.sigstore.dev \
|
|
ghcr.io/org/myapp:$COMMIT_SHA
|
|
|
|
# Offline: verify with bundled certificate
|
|
cosign verify-attestation \
|
|
--type https://stellaops.io/attestation/scan/v1 \
|
|
--certificate /path/to/cert.pem \
|
|
--certificate-chain /path/to/chain.pem \
|
|
--offline \
|
|
ghcr.io/org/myapp:$COMMIT_SHA
|
|
```
|
|
|
|
#### GitHub Actions Integration
|
|
|
|
```yaml
|
|
- name: Verify attestation
|
|
run: |
|
|
stellaops proof verify \
|
|
--image ghcr.io/org/myapp:${{ github.sha }} \
|
|
--attestation-type scan-result \
|
|
--check-rekor \
|
|
--fail-on-missing
|
|
|
|
- name: Push to registry (only if verified)
|
|
if: success()
|
|
run: |
|
|
docker push ghcr.io/org/myapp:${{ github.sha }}
|
|
```
|
|
|
|
#### GitLab CI Integration
|
|
|
|
```yaml
|
|
verify:
|
|
stage: verify
|
|
script:
|
|
- stellaops proof verify
|
|
--image $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
|
--attestation-type scan-result
|
|
--check-rekor
|
|
--fail-on-missing
|
|
rules:
|
|
- if: $CI_COMMIT_BRANCH == "main"
|
|
```
|
|
|
|
**Related Documentation:**
|
|
- [Score Proofs Runbook](../operations/score-proofs-runbook.md)
|
|
- [Proof Verification Runbook](../operations/proof-verification-runbook.md)
|
|
|
|
### 6. SARIF Integration
|
|
|
|
CLI outputs SARIF for IDE and GitHub integration:
|
|
|
|
```json
|
|
{
|
|
"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
|
|
"version": "2.1.0",
|
|
"runs": [
|
|
{
|
|
"tool": {
|
|
"driver": {
|
|
"name": "StellaOps",
|
|
"version": "2.1.0",
|
|
"informationUri": "https://stellaops.io"
|
|
}
|
|
},
|
|
"results": [
|
|
{
|
|
"ruleId": "CVE-2024-1234",
|
|
"level": "error",
|
|
"message": {
|
|
"text": "Critical vulnerability in lodash@4.17.20"
|
|
},
|
|
"locations": [
|
|
{
|
|
"physicalLocation": {
|
|
"artifactLocation": {
|
|
"uri": "package-lock.json"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### 7. Attestation Storage
|
|
|
|
If `--attestation` is specified, CLI stores attestation:
|
|
|
|
```bash
|
|
# View attestation
|
|
stellaops attestation show --scan $SCAN_ID
|
|
|
|
# Verify attestation
|
|
```
|
|
|
|
### 8. PR/MR Comment and Status Integration
|
|
|
|
StellaOps can post scan results as PR/MR comments and status checks for visibility directly in the SCM platform.
|
|
|
|
#### GitHub PR Integration
|
|
|
|
When scanning PRs, the system can:
|
|
- Post a summary comment with findings count and severity breakdown
|
|
- Create check runs with inline annotations
|
|
- Update commit status with pass/fail verdict
|
|
|
|
```yaml
|
|
# GitHub Actions with PR comments
|
|
- name: Scan with PR feedback
|
|
run: |
|
|
stellaops scan myapp:${{ github.sha }} \
|
|
--policy production \
|
|
--pr-comment \
|
|
--check-run \
|
|
--github-token ${{ secrets.GITHUB_TOKEN }}
|
|
```
|
|
|
|
Example PR comment format:
|
|
|
|
```markdown
|
|
## StellaOps Scan Results
|
|
|
|
**Verdict:** :warning: WARN
|
|
|
|
| Severity | Count |
|
|
|----------|-------|
|
|
| Critical | 0 |
|
|
| High | 2 |
|
|
| Medium | 5 |
|
|
| Low | 12 |
|
|
|
|
### Findings Requiring Attention
|
|
|
|
| CVE | Severity | Package | Status |
|
|
|-----|----------|---------|--------|
|
|
| CVE-2026-1234 | High | lodash@4.17.21 | Fix available: 4.17.22 |
|
|
| CVE-2026-5678 | High | express@4.18.0 | VEX: Not affected |
|
|
|
|
<details>
|
|
<summary>View full report</summary>
|
|
|
|
[Download SARIF](https://stellaops.example.com/scans/abc123/sarif)
|
|
[View in Console](https://stellaops.example.com/scans/abc123)
|
|
|
|
</details>
|
|
|
|
---
|
|
*Scan ID: abc123 | Policy: production | [Evidence](https://stellaops.example.com/evidence/abc123)*
|
|
```
|
|
|
|
#### GitLab MR Integration
|
|
|
|
For GitLab Merge Requests:
|
|
- Post MR notes with findings summary
|
|
- Update commit status on the pipeline
|
|
- Create discussion threads for critical findings
|
|
|
|
```yaml
|
|
# GitLab CI with MR feedback
|
|
scan:
|
|
stage: test
|
|
script:
|
|
- stellaops scan $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA \
|
|
--policy production \
|
|
--mr-comment \
|
|
--commit-status \
|
|
--gitlab-token $CI_JOB_TOKEN
|
|
rules:
|
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
|
```
|
|
|
|
#### Comment Behavior Options
|
|
|
|
| Option | Description | Default |
|
|
|--------|-------------|---------|
|
|
| `--pr-comment` / `--mr-comment` | Post summary comment | false |
|
|
| `--check-run` | Create GitHub check run with annotations | false |
|
|
| `--commit-status` | Update commit status | false |
|
|
| `--update-existing` | Edit previous comment instead of new | true |
|
|
| `--collapse-details` | Use collapsible sections for long output | true |
|
|
| `--evidence-link` | Include link to evidence bundle | true |
|
|
|
|
#### Evidence Anchoring in Comments
|
|
|
|
Comments include evidence references for auditability:
|
|
|
|
- **Scan ID**: Unique identifier for the scan
|
|
- **Policy Version**: The policy version used for evaluation
|
|
- **Attestation Digest**: DSSE envelope digest for signed results
|
|
- **Rekor Entry**: Log index when transparency logging is enabled
|
|
|
|
#### Error Handling
|
|
|
|
| Scenario | Behavior |
|
|
|----------|----------|
|
|
| No SCM token | Skip comment, log warning |
|
|
| API rate limit | Retry with backoff, then skip |
|
|
| Comment too long | Truncate with link to full report |
|
|
| PR already merged | Skip comment |
|
|
|
|
#### Evidence-First Annotation Format
|
|
|
|
PR/MR comments use ASCII-only output for determinism and maximum compatibility:
|
|
|
|
```
|
|
## StellaOps Security Scan
|
|
|
|
**Verdict:** [BLOCKING] Policy violation detected
|
|
|
|
| Status | Finding | Package | Action |
|
|
| --- | --- | --- | --- |
|
|
| [+] New | CVE-2026-1234 | lodash@4.17.21 | Fix: 4.17.22 |
|
|
| [-] Fixed | CVE-2025-9999 | express@4.17.0 | Resolved |
|
|
| [^] Upgraded | CVE-2026-5678 | axios@1.0.0 | High -> Medium |
|
|
| [v] Downgraded | CVE-2026-4321 | react@18.0.0 | Medium -> Low |
|
|
|
|
### Evidence
|
|
|
|
| Field | Value |
|
|
| --- | --- |
|
|
| Attestation Digest | sha256:abc123... |
|
|
| Policy Verdict | FAIL |
|
|
| Verify Command | `stellaops verify --digest sha256:abc123...` |
|
|
|
|
---
|
|
*[OK] 12 findings unchanged | Policy: production v2.1.0*
|
|
```
|
|
|
|
**ASCII Indicator Reference:**
|
|
|
|
| Indicator | Meaning |
|
|
|-----------|---------|
|
|
| `[OK]` | Pass / Success |
|
|
| `[BLOCKING]` | Fail / Hard gate triggered |
|
|
| `[WARNING]` | Soft gate / Advisory |
|
|
| `[+]` | New finding introduced |
|
|
| `[-]` | Finding fixed / removed |
|
|
| `[^]` | Severity upgraded |
|
|
| `[v]` | Severity downgraded |
|
|
|
|
#### Offline Mode
|
|
|
|
In air-gapped environments:
|
|
- Comments are queued locally
|
|
- Export comment payload for manual posting
|
|
- Generate markdown file for offline review
|
|
stellaops attestation verify --image myapp:v1.2.3 --policy production
|
|
```
|
|
|
|
Attestation is stored as DSSE envelope:
|
|
```json
|
|
{
|
|
"payloadType": "application/vnd.in-toto+json",
|
|
"payload": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEi...",
|
|
"signatures": [
|
|
{
|
|
"keyid": "sha256:abc123...",
|
|
"sig": "MEQCI..."
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
## Gate Behaviors
|
|
|
|
### Soft Gate (Warning Only)
|
|
|
|
```yaml
|
|
# .stellaops.yaml
|
|
gates:
|
|
ci:
|
|
mode: soft # Report but don't fail
|
|
notify:
|
|
- slack://security-channel
|
|
```
|
|
|
|
### Hard Gate (Blocking)
|
|
|
|
```yaml
|
|
gates:
|
|
ci:
|
|
mode: hard # Fail pipeline on violations
|
|
exceptions:
|
|
- CVE-2024-9999 # Known false positive
|
|
```
|
|
|
|
### Progressive Gate
|
|
|
|
```yaml
|
|
gates:
|
|
ci:
|
|
mode: progressive
|
|
thresholds:
|
|
- branch: main
|
|
max_critical: 0
|
|
max_high: 5
|
|
- branch: develop
|
|
max_critical: 2
|
|
max_high: 20
|
|
- branch: feature/*
|
|
mode: soft # Warn only on feature branches
|
|
```
|
|
|
|
## Data Contracts
|
|
|
|
### CLI Scan Output Schema
|
|
|
|
```typescript
|
|
interface CliScanOutput {
|
|
scan_id: string;
|
|
image: string;
|
|
digest: string;
|
|
verdict: 'PASS' | 'WARN' | 'FAIL';
|
|
confidence: number;
|
|
summary: {
|
|
critical: number;
|
|
high: number;
|
|
medium: number;
|
|
low: number;
|
|
};
|
|
violations: Array<{
|
|
cve: string;
|
|
severity: string;
|
|
package: string;
|
|
rule: string;
|
|
message: string;
|
|
}>;
|
|
attestation?: {
|
|
digest: string;
|
|
rekor_log_index?: number;
|
|
};
|
|
timing: {
|
|
queued_ms: number;
|
|
scan_ms: number;
|
|
policy_ms: number;
|
|
total_ms: number;
|
|
};
|
|
}
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
| Error | Exit Code | Recovery |
|
|
|-------|-----------|----------|
|
|
| Auth failure | 2 | Check credentials |
|
|
| Image not found | 2 | Verify image reference |
|
|
| API timeout | 2 | Retry with --timeout |
|
|
| Policy not found | 2 | Check policy name |
|
|
| Network error | 2 | Check connectivity |
|
|
|
|
## Observability
|
|
|
|
### Metrics
|
|
|
|
| Metric | Type | Labels |
|
|
|--------|------|--------|
|
|
| `cli_scan_total` | Counter | `verdict`, `ci_platform` |
|
|
| `cli_scan_duration_seconds` | Histogram | `ci_platform` |
|
|
| `cli_gate_blocked_total` | Counter | `policy`, `reason` |
|
|
|
|
### CI/CD Annotations
|
|
|
|
GitHub Actions annotations:
|
|
```
|
|
::error file=package-lock.json::CVE-2024-1234: Critical vulnerability in lodash@4.17.20
|
|
::warning file=Dockerfile::Using outdated base image
|
|
```
|
|
|
|
## Related Flows
|
|
|
|
- [Scan Submission Flow](02-scan-submission-flow.md) - Underlying scan mechanics
|
|
- [Policy Evaluation Flow](04-policy-evaluation-flow.md) - Policy rule details
|
|
- [Binary Delta Attestation Flow](15-binary-delta-attestation-flow.md) - Attestation details
|