The System Security Plan (SSP) workflow in Judge API is a sophisticated multi-stage pipeline that generates, transforms, and stores OSCAL-compliant SSP documents. This workflow leverages native Dapr activities for better resource isolation, error handling, and reliability.
Activity: CloneRepositoriesActivity
The workflow begins by cloning source code repositories associated with the input product. These repositories contain the system implementation that will be analyzed for compliance.
- Input: Repository URLs from the product configuration
- Process:
- Clones repositories to a temporary workspace (
/tmp/ssp-repos) - Creates tar.gz archive of all repositories
- Uploads archive to blob storage for sharing between activities
- Clones repositories to a temporary workspace (
- Output:
- Local paths to cloned repositories
- Blob storage key for the archived repositories
Activity: SSPGeneratorActivity
This is the core activity that uses Claude AI (via AgentFlow) to analyze the codebase and generate an OSCAL-compliant SSP.
- Repository Extraction: If repositories were archived to blob storage, extracts them to workspace
- OSCAL SSP Creation: Uses
oscal.CreateSSPHandlerto create initial SSP structure with UUID - AgentFlow Workflow Execution:
- Build Inventory Step: Analyzes repositories to identify system components
- Implement AC-2 Step: Maps components to AC-2 control statements with evidence
- Validate Coverage Step: Ensures all AC-2 statements are covered
- Statement-level control implementation (not just control-level)
- Evidence tracking with gaps identification
- Implementation status determination (implemented/partial/planned)
- Component-based control mapping
- OSCAL JSON (
{uuid}.json): Standard OSCAL SSP format - Archivista-compatible JSON (
ssp.json): Transformed for Archivista storage - Markdown (
ssp.md): Human-readable SSP document
Activity: PDFConverterActivity
Converts the markdown SSP into a PDF report using Pandoc and pdflatex.
- Input: Markdown file path from SSP generator
- Process: Pandoc markdown → LaTeX → PDF conversion
- Output: PDF file path
Activity: BlobUploadActivity
Uploads the generated SSP document (PDF or JSON) to blob storage for long-term retention.
- Storage Key Format:
ssp/{uuid}/{productId}.ssp.{ext} - Content Types:
application/pdforapplication/json
Activity: CreateReportActivity
Creates a report entry in the database linking the SSP to the product.
- Report Type:
ssp - Reference: URI to the blob storage location
Activities: WitnessSignActivity + ArchivistaUploadActivity
This critical stage ensures the SSP is cryptographically signed and stored in Archivista for compliance attestation.
-
DSSE Envelope Creation:
- Creates in-toto subject with SHA256 digest of SSP JSON
- Wraps SSP in witness predicate with type
https://witness.dev/attestations/ssp/v0.1 - Sets payload type to
oscal/sspto trigger Archivista's SSP parser
-
Signing:
- Uses AWS KMS for cryptographic signing (default: local development key)
- Can include timestamp authorities for non-repudiation
-
Archivista Upload:
- Uploads signed DSSE envelope to Archivista
- Archivista's
storeSSPfunction parses the OSCAL structure - Stores SSP components in relational database tables
The workflow includes a transformation step between the raw OSCAL SSP and the Archivista-compatible format. This is handled in the generateArchivistaJSON function.
- Schema Mismatches: AgentFlow/OscalSynth may produce SSP JSON that doesn't 100% match Archivista's expected schema
- Custom Extensions: Judge may add custom fields (like evidence tracking) not in standard OSCAL
- Versioning Issues: Different OSCAL versions may have structural differences
// Determine which data to use for Archivista storage
dataForArchivista := sspReportResult.SSPJSONData
if sspReportResult.ArchivistaCompatibleData != "" {
// Use transformed data if available
dataForArchivista = sspReportResult.ArchivistaCompatibleData
}- Preferred: Fix upstream in Archivista's schema parser
- Alternative: Fix downstream in AgentFlow/OscalSynth output
- Band-aid: Apply transformations during conversion
When the DSSE envelope with payload type oscal/ssp is received, Archivista:
- Parses SSP Structure: Unmarshals JSON into
ssp.Rootstruct - Creates Database Records:
SSPMetadata: Title, version informationSystemSecurityPlan: Main SSP record with UUIDSSPSystemCharacteristics: System description and propertiesSSPSystemImplementation: Components and their relationshipsSSPComponent: Individual system componentsSSPControlImplementation: How controls are satisfied
Each activity runs in the Dapr sidecar with:
- Automatic retry logic for transient failures
- Resource isolation preventing crashes from affecting judge-api
- Built-in timeout management
Some operations are marked as non-critical:
- PDF conversion failures don't fail the workflow
- Archivista storage failures are logged but don't block completion
These will fail the workflow:
- Repository cloning failures (if repos provided)
- SSP generation failures
- Report metadata creation failures
GATEWAY_URL: GraphQL gateway for queriesARCHIVISTA_URL: Archivista service endpointSSP_ENABLED: Master switch for SSP functionalityANTHROPIC_API_KEY: Claude AI API key for AgentFlowWORKFLOW_SIGNER_KMS_URI: KMS key for DSSE signing
ssp:
enabled: true
agentflowModel: "claude-sonnet-4-20250514"- Cloned repositories:
/tmp/ssp-repos/ - SSP output:
/tmp/ssp-output/ - Workspace:
/tmp/ssp-workspace-{timestamp}/
- Blob Storage:
s3://judge/ssp/{uuid}/{productId}.ssp.{ext} - Archivista: DSSE envelopes with gitoid references
- Database: Report metadata linking to blob storage
- Cryptographic Signing: All SSPs are signed using AWS KMS keys
- In-toto Attestations: SSPs wrapped in DSSE envelopes with proper subjects
- SHA256 Digests: Content integrity verified through cryptographic hashes
- Tenant Isolation: SSPs stored with tenant ID for multi-tenancy support
[SSP Workflow {instanceID}]: Workflow-level operationsSSPGeneratorActivity: AgentFlow execution detailsArchivistaUploadActivity: Storage operationsFailed to unmarshal ssp payload: Schema mismatch indicators
-
"Failed to unmarshal ssp payload":
- Check SSP JSON structure against
ssp.Rootschema - Verify OSCAL compliance
- Review transformation logic
- Check SSP JSON structure against
-
"PDF conversion failed":
- Verify pandoc/pdflatex installation
- Check markdown formatting
-
"Archivista upload failed":
- Verify authentication token
- Check network connectivity
- Review DSSE envelope structure
- Extended Control Coverage: Currently focused on AC-2, expand to full control catalog
- Enhanced Evidence Collection: Integrate with runtime attestations
- Schema Versioning: Better handling of OSCAL version differences
- Caching: Repository analysis results for performance
- Incremental Updates: Support for updating existing SSPs
- TODO: Remove
ArchivistaCompatibleDataworkaround once schema alignment is complete - TODO: Implement proper OSCAL version negotiation
- TODO: Add support for multiple control implementations beyond AC-2