# Export Flow ## Overview The Export Flow describes how StellaOps generates and delivers reports, evidence bundles, and compliance documentation. Exports can be triggered on-demand or scheduled, and support multiple formats including PDF, Excel, JSON, and SARIF. **Business Value**: Automated, auditable exports reduce manual effort for compliance reporting and enable integration with external systems. ## Actors | Actor | Type | Role | |-------|------|------| | User | Human | Requests or schedules exports | | Console | System | UI for export configuration | | Gateway | Service | Routes export requests | | ExportCenter | Service | Orchestrates export generation | | Scanner | Service | Provides scan data | | Policy | Service | Provides policy verdicts | | EvidenceLocker | Service | Stores sealed evidence | | RustFS | Storage | Stores export artifacts | ## Prerequisites - User has export permissions for the resource - Data exists for the requested export scope - Export template configured (for custom formats) ## Supported Export Formats | Format | Extension | Use Case | |--------|-----------|----------| | PDF | `.pdf` | Human-readable reports | | Excel | `.xlsx` | Data analysis, spreadsheet import | | JSON | `.json` | API integration, automation | | SARIF | `.sarif` | IDE integration, GitHub Code Scanning | | CycloneDX | `.cdx.json` | SBOM exchange | | SPDX | `.spdx.json` | SBOM compliance | | CSV | `.csv` | Data export, legacy systems | ## Flow Diagram ``` ┌─────────────────────────────────────────────────────────────────────────────────┐ │ Export Flow │ └─────────────────────────────────────────────────────────────────────────────────┘ ┌────────┐ ┌─────────┐ ┌─────────┐ ┌────────────┐ ┌──────────────┐ ┌────────┐ │ User │ │ Console │ │ Gateway │ │ExportCenter│ │EvidenceLocker│ │ RustFS │ └───┬────┘ └────┬────┘ └────┬────┘ └─────┬──────┘ └──────┬───────┘ └───┬────┘ │ │ │ │ │ │ │ Request │ │ │ │ │ │ export │ │ │ │ │ │───────────>│ │ │ │ │ │ │ │ │ │ │ │ │ POST │ │ │ │ │ │ /exports │ │ │ │ │ │───────────>│ │ │ │ │ │ │ │ │ │ │ │ │ Forward │ │ │ │ │ │────────────>│ │ │ │ │ │ │ │ │ │ │ 202 │ │ │ │ │ │ Accepted │ │ │ │ │ │<───────────│ │ │ │ │ │ │ │ │ │ │ Export │ │ │ │ │ │ queued │ │ │ │ │ │<───────────│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ Query scan │ │ │ │ │ │ data │ │ │ │ │ │───┐ │ │ │ │ │ │ │ │ │ │ │ │ │<──┘ │ │ │ │ │ │ │ │ │ │ │ │ Query policy │ │ │ │ │ │ verdicts │ │ │ │ │ │───┐ │ │ │ │ │ │ │ │ │ │ │ │ │<──┘ │ │ │ │ │ │ │ │ │ │ │ │ Render │ │ │ │ │ │ template │ │ │ │ │ │───┐ │ │ │ │ │ │ │ │ │ │ │ │ │<──┘ │ │ │ │ │ │ │ │ │ │ │ │ Store artifact │ │ │ │ │ │────────────────────────────────> │ │ │ │ │ │ │ │ │ │ {path} │ │ │ │ │ │<──────────────────────────────── │ │ │ │ │ │ │ │ │ │ Seal evidence │ │ │ │ │ │───────────────>│ │ │ │ │ │ │ │ │ │ │ │ Sealed bundle │ │ │ │ │ │<───────────────│ │ │ │ │ │ │ │ │ │ │ │ Store sealed │ │ │ │ │ │────────────────────────────────> │ │ │ │ │ │ │ WebSocket: │ │ │ │ │ │ export │ │ │ │ │ │ ready │ │ │ │ │ │<───────────│ │ │ │ │ │ │ │ │ │ │ ``` ## Step-by-Step ### 1. Export Request User requests export via Console or API: ```http POST /api/v1/exports HTTP/1.1 Authorization: Bearer {jwt} X-Tenant-Id: acme-corp Content-Type: application/json { "type": "scan_report", "format": "pdf", "scope": { "scan_ids": ["scan-7f3a9b2c-..."], "date_range": null }, "options": { "include_sbom": true, "include_evidence": true, "template": "compliance-executive" } } ``` ### 2. Export Job Creation ExportCenter creates export job: ```json { "export_id": "exp-456def", "status": "queued", "type": "scan_report", "format": "pdf", "created_at": "2024-12-29T10:30:00Z", "estimated_completion": "PT2M" } ``` ### 3. Data Gathering ExportCenter queries multiple data sources: | Source | Query | Data | |--------|-------|------| | Scanner | `GET /internal/scans/{id}` | Scan results, findings | | Policy | `GET /internal/verdicts/{scan_id}` | Policy verdicts | | VexLens | `GET /internal/vex/applied/{scan_id}` | VEX statements | | SbomService | `GET /internal/sboms/{digest}` | SBOM document | ### 4. Template Rendering ExportCenter applies report template: ``` Templates Available: ├── compliance-executive # High-level summary for executives ├── compliance-detailed # Full findings with remediation ├── audit-evidence # Audit trail with attestations ├── developer-sarif # IDE-compatible SARIF output └── custom-{tenant} # Tenant-specific templates ``` PDF generation uses Chromium for high-fidelity rendering: ```typescript const pdf = await chromium.pdf({ content: renderedHtml, format: 'A4', margin: { top: '1cm', bottom: '1cm' }, displayHeaderFooter: true, headerTemplate: '
StellaOps Security Report
', footerTemplate: '
Page
' }); ``` ### 5. Artifact Storage Export artifact stored in RustFS: ``` blobs/ └── exports/ └── acme-corp/ └── 2024/ └── 12/ └── exp-456def/ ├── report.pdf ├── sbom.cdx.json └── manifest.json ``` Manifest tracks export contents: ```json { "export_id": "exp-456def", "created_at": "2024-12-29T10:32:00Z", "artifacts": [ {"name": "report.pdf", "size": 245678, "sha256": "abc..."}, {"name": "sbom.cdx.json", "size": 89012, "sha256": "def..."} ], "expires_at": "2025-01-28T10:32:00Z" } ``` ### 6. Evidence Sealing (Optional) If evidence sealing requested, EvidenceLocker creates sealed bundle: ```json { "bundle_id": "bnd-789ghi", "sealed_at": "2024-12-29T10:32:00Z", "contents": [ {"type": "scan_result", "id": "scan-7f3a9b2c-..."}, {"type": "sbom", "digest": "sha256:..."}, {"type": "policy_verdict", "id": "verdict-..."}, {"type": "attestation", "digest": "sha256:..."} ], "merkle_root": "sha256:merkle-root...", "signature": "base64:signature..." } ``` ### 7. Delivery Export delivered via: - **Download**: Signed URL with expiration - **Email**: Attachment or link (based on size) - **Webhook**: POST to configured endpoint - **S3**: Direct upload to external bucket Download URL generation: ```http GET /api/v1/exports/exp-456def/download HTTP/1.1 Authorization: Bearer {jwt} Response: { "download_url": "https://storage.stellaops.local/exports/exp-456def/report.pdf?sig=...", "expires_at": "2024-12-29T11:32:00Z" } ``` ## Export Types | Type | Description | Formats | |------|-------------|---------| | `scan_report` | Single scan results | PDF, JSON, SARIF | | `scan_summary` | Multiple scans summary | PDF, Excel, CSV | | `sbom` | Software Bill of Materials | CycloneDX, SPDX | | `vulnerability_report` | CVE-focused report | PDF, Excel, CSV | | `policy_compliance` | Policy compliance status | PDF, JSON | | `evidence_bundle` | Sealed evidence package | ZIP, TAR.GZ | | `audit_log` | Activity audit trail | JSON, CSV | ## Data Contracts ### Export Request Schema ```typescript interface ExportRequest { type: ExportType; format: ExportFormat; scope: { scan_ids?: string[]; image_refs?: string[]; date_range?: { start: string; end: string; }; policy_sets?: string[]; }; options?: { include_sbom?: boolean; include_evidence?: boolean; include_remediation?: boolean; template?: string; custom_fields?: Record; }; delivery?: { method: 'download' | 'email' | 'webhook' | 's3'; config?: DeliveryConfig; }; } ``` ### Export Response Schema ```typescript interface ExportResponse { export_id: string; status: 'queued' | 'processing' | 'completed' | 'failed'; type: ExportType; format: ExportFormat; created_at: string; completed_at?: string; artifacts?: Array<{ name: string; size: number; sha256: string; download_url?: string; }>; error?: string; } ``` ## Scheduled Exports Configure recurring exports via cron: ```yaml schedules: - name: weekly-executive-summary cron: "0 8 * * MON" # Every Monday at 8 AM export: type: scan_summary format: pdf scope: date_range: start: "-7d" end: "now" options: template: compliance-executive delivery: method: email config: to: ["security-leads@acme.com"] subject: "Weekly Security Summary - {{week}}" ``` ## Error Handling | Error | Recovery | |-------|----------| | Data not found | Return 404 with scope details | | Template error | Fall back to default template | | Storage failure | Retry with exponential backoff | | PDF generation timeout | Simplify report, retry | | Delivery failure | Queue for retry, notify user | ## Observability ### Metrics | Metric | Type | Labels | |--------|------|--------| | `export_requests_total` | Counter | `type`, `format` | | `export_duration_seconds` | Histogram | `type`, `format` | | `export_size_bytes` | Histogram | `type`, `format` | | `export_failures_total` | Counter | `type`, `reason` | ### Trace Context ``` export-request ├── data-gather │ ├── scanner-query │ ├── policy-query │ └── vexlens-query ├── template-render ├── artifact-storage ├── evidence-seal (optional) └── delivery ``` ## Related Flows - [Scan Submission Flow](02-scan-submission-flow.md) - Source of scan data - [Evidence Bundle Export Flow](13-evidence-bundle-export-flow.md) - Detailed evidence packaging - [Dashboard Data Flow](01-dashboard-data-flow.md) - Data aggregation patterns