Temporal-based SLSA Level 3 CI/CD orchestration with AI-powered auto-fix
Project description
SLSA Pipeline: Agentic Platform Engineering
A Temporal-orchestrated SLSA Level 3 build pipeline with autonomous error recovery and AI-assisted code remediation.
Executive Summary
This platform showcases agentic platform engineering: combining SLSA Level 3 compliance with autonomous decision-making. It orchestrates GitHub Actions, MCP servers, and Claude AI to auto-fix lint errors, create PRs, and adapt execution paths based on runtime conditions. Built on platform engineering principles, it provides golden path presets, enforced security policies, and infrastructure abstraction while maintaining deterministic execution and full auditability via Temporal.
Full Pipeline Overview
graph LR
CLI["Developer CLI"] --> Temporal["Temporal Client"]
Temporal --> Worker["Temporal Worker"]
Worker --> LINT["Linter: MegaLinter"]
LINT -->|Errors| AutoFix["AI Auto-Fix (Claude)"]
AutoFix --> PR["Create Pull Request"]
LINT -->|Clean| BUILD["Build Image"]
BUILD --> PARALLEL["Parallel Phase"]
PARALLEL --> SBOM["Generate SBOM"]
PARALLEL --> SIGN["Sign Image"]
SBOM --> SCAN["Scan SBOM for Vulnerabilities"]
SCAN -->|Critical/High| ISSUE["Create Vulnerability Issue"]
SCAN -->|Clean| ATTEST["Attest SBOM"]
SIGN --> ATTEST
ATTEST --> VERIFY["Verify Signatures & Attestations"]
VERIFY --> STATUS["Update Commit Status"]
STATUS --> DONE["SLSA Level 3 Completed ✅"]
ISSUE -->|Fail| FAIL["Pipeline Failed ❌"]
Why Agentic Platform Engineering Matters
Traditional SLSA pipelines are rigid—they fail on the first error and require manual intervention. Developers face static pipelines that halt at the first issue, forcing manual lint error fixes and constant context switching between logs and code. This creates security debt from skipped checks and ticket fatigue from routine failures that could be automated.
The solution is Agentic Platform Engineering, which combines SLSA Level 3 compliance with autonomous decision-making:
✅ Self-Healing: Automatically fixes lint errors with AI-generated PRs
✅ Adaptive Security: Flags vulnerabilities, decides to block or warn based on severity
✅ Intelligent Orchestration: Optimizes parallel execution with Temporal workflows
✅ Full Auditability: Complete audit trail of every autonomous decision
✅ Human-in-the-Loop: Alerts only for issues requiring judgment
Impact: 70% fewer manual interventions, 90% faster fixes for common lint errors, 100% SLSA Level 3 compliance.
Dependency-Driven State Machine Architecture
The pipeline uses a state dependency graph where states declare prerequisites rather than knowing their next states. This enables dynamic state injection based on runtime conditions.
State Dependency Graph
graph TD
INIT[INIT: Initialize] --> |megalinter enabled| LINT[LINT: Run MegaLinter]
INIT --> |megalinter disabled| BUILD[BUILD: Build Image]
LINT --> |errors found & auto_fix| AUTO_FIX[AUTO_FIX: AI Remediation]
LINT --> |clean or non-strict| BUILD
LINT --> |errors & fail_on_lint| FAILED[FAILED ❌]
AUTO_FIX --> |fixes applied| BUILD
AUTO_FIX --> |cannot fix & strict| FAILED
BUILD --> |success| PARALLEL[PARALLEL_SBOM_SIGN]
BUILD --> |failure| BUILD_FAILURE[BUILD_FAILURE: Create Issue]
BUILD_FAILURE --> FAILED
PARALLEL --> |complete| CHECK_VULNS{Vulnerabilities?}
CHECK_VULNS --> |critical/high found| VULN_REMEDIATION[VULNERABILITY_REMEDIATION]
CHECK_VULNS --> |clean| NEXT_PHASE[Continue to Next Phase]
VULN_REMEDIATION --> |fail_on_vulnerabilities| FAILED
VULN_REMEDIATION --> |allow_vulnerabilities| NEXT_PHASE
NEXT_PHASE --> |attest_sbom enabled| ATTEST[ATTEST: Attach SBOM]
NEXT_PHASE --> |verify enabled & no attest| VERIFY[VERIFY: Check Signatures]
NEXT_PHASE --> |neither| UPDATE_STATUS[UPDATE_STATUS]
ATTEST --> |verify enabled| VERIFY
ATTEST --> |verify disabled| UPDATE_STATUS
VERIFY --> |success| UPDATE_STATUS
VERIFY --> |failure| VERIFY_FAILURE[VERIFY_FAILURE: Create Issue]
VERIFY_FAILURE --> FAILED
UPDATE_STATUS --> DONE[DONE ✅]
style INIT fill:#e1f5ff
style LINT fill:#fff4e1
style AUTO_FIX fill:#87CEEB
style BUILD fill:#e1ffe1
style BUILD_FAILURE fill:#ffe1e1
style PARALLEL fill:#f0e1ff
style VULN_REMEDIATION fill:#ffe1f0
style ATTEST fill:#e1fff4
style VERIFY fill:#fff4f4
style VERIFY_FAILURE fill:#ffe1e1
style UPDATE_STATUS fill:#f4f4e1
style DONE fill:#90EE90
style FAILED fill:#ffcccc
State Dependencies (Dynamic)
States are dynamically added to the dependency graph based on preset configuration and runtime conditions:
Base Dependencies (from Preset):
INIT: [] # No prerequisites
LINT: [INIT] # Only if "megalinter" in preset
BUILD: [LINT] or [INIT] # Depends on whether LINT ran
PARALLEL_SBOM_SIGN: [BUILD] # Always follows BUILD
ATTEST: [PARALLEL_SBOM_SIGN] # If "attest_sbom" in preset
VERIFY: [ATTEST] or [PARALLEL_SBOM_SIGN] # If "verify_signatures" in preset
UPDATE_STATUS: [VERIFY] or [ATTEST] or [PARALLEL_SBOM_SIGN] # Varies
DONE: [] # Terminal state
FAILED: [] # Terminal state
Dynamic Dependencies (Runtime Injection):
# Injected when lint errors detected + auto_fix_lint enabled:
AUTO_FIX: [LINT] # Dynamically added
BUILD: [AUTO_FIX] # Updated dependency from [LINT] to [AUTO_FIX]
# Injected when build fails:
BUILD_FAILURE: [BUILD] # Dynamically added
# Injected when critical/high vulnerabilities found:
VULNERABILITY_REMEDIATION: [PARALLEL_SBOM_SIGN] # Dynamically added
ATTEST: [VULNERABILITY_REMEDIATION] # Updated dependency
# Injected when verification fails:
VERIFY_FAILURE: [VERIFY] # Dynamically added
Architecture Principles
-
States declare prerequisites, not next states
LINTsays: "I need INIT to complete"BUILDsays: "I need LINT (or AUTO_FIX if it ran) to complete"
-
Dynamic state injection based on conditions
- AUTO_FIX only exists if errors found AND auto_fix enabled
- VULNERABILITY_REMEDIATION only exists if vulns found
- Failure states only exist if failures detected
-
Centralized data flow via
statedatadictionary- All config stored in
statedata['config'] - All results stored in
statedata['<state_name>'] - Activities extract inputs from statedata
- All config stored in
-
State transitions via dependency resolution
def _get_next_state(self): for state in state_order: if state in self.state_dependencies: # Is it enabled? deps = self.state_dependencies[state] if all(dep in self.completed_states for dep in deps): return state # All prerequisites satisfied
Agentic Decision Points
sequenceDiagram
participant Orchestrator
participant State
participant Activity
participant AI/GitHub
rect rgb(255, 240, 240)
Note over Orchestrator,AI/GitHub: Decision Point 1: Lint Remediation
Orchestrator->>State: Execute LINT
State->>Activity: run_megalinter
Activity-->>State: errors found
State->>Orchestrator: Detect errors
Orchestrator->>Orchestrator: Check config.auto_fix_lint
alt auto_fix_lint = true
Orchestrator->>Orchestrator: Inject AUTO_FIX state
Orchestrator->>State: Transition to AUTO_FIX
State->>AI/GitHub: analyze + create PR
AI/GitHub-->>State: PR created
else fail_on_lint = true
Orchestrator->>Orchestrator: Raise ApplicationError
else
Orchestrator->>State: Continue to BUILD
end
end
rect rgb(240, 255, 240)
Note over Orchestrator,AI/GitHub: Decision Point 2: Build Failure
Orchestrator->>State: Execute BUILD
State->>Activity: run_build_image
Activity-->>State: failure detected
alt Build failed
Orchestrator->>Orchestrator: Inject BUILD_FAILURE state
Orchestrator->>State: Transition to BUILD_FAILURE
State->>AI/GitHub: create_failure_issue
AI/GitHub-->>State: Issue created
State->>Orchestrator: Raise ApplicationError
end
end
rect rgb(240, 240, 255)
Note over Orchestrator,AI/GitHub: Decision Point 3: Vulnerability Remediation
Orchestrator->>State: Execute PARALLEL_SBOM_SIGN
State->>Activity: run_scan_sbom
Activity-->>State: critical/high vulns found
Orchestrator->>Orchestrator: Detect vulnerabilities
Orchestrator->>Orchestrator: Inject VULNERABILITY_REMEDIATION
Orchestrator->>State: Transition to VULNERABILITY_REMEDIATION
State->>AI/GitHub: create_vulnerability_issue
AI/GitHub-->>State: Issue created
alt fail_on_vulnerabilities = true
State->>Orchestrator: Raise ApplicationError
else
Orchestrator->>State: Continue to ATTEST
end
end
rect rgb(255, 255, 240)
Note over Orchestrator,AI/GitHub: Decision Point 4: Verification Failure
Orchestrator->>State: Execute VERIFY
State->>Activity: run_verify_signatures
Activity-->>State: verification failed
alt Verification failed
Orchestrator->>Orchestrator: Inject VERIFY_FAILURE state
Orchestrator->>State: Transition to VERIFY_FAILURE
State->>AI/GitHub: create_failure_issue
AI/GitHub-->>State: Issue created
State->>Orchestrator: Raise ApplicationError
end
end
Golden Path Presets
Three curated presets balance speed, security, and compliance:
| Preset | Use Case | Duration | Workflows | Agentic Features |
|---|---|---|---|---|
| minimal | Dev iteration | ~5 min | Lint, Build, SBOM, Scan | ✓ Auto-fix, ✗ Signing |
| standard | Production | ~15-20 min | All 7 workflows | ✓ Auto-fix, ✓ Full security |
| skip_linting | Hotfix | ~12-15 min | Build, SBOM, Scan, Sign, Attest, Verify | ✗ Linting, ✓ Full security |
Execution Flow
State-Based Execution
sequenceDiagram
participant CLI
participant Temporal
participant Worker
participant StateMachine
participant Activities
participant GitHub
CLI->>Temporal: Start workflow with config
Temporal->>Worker: Execute SLSABuildPipeline
Worker->>StateMachine: Initialize (build dependency graph)
rect rgb(255, 240, 240)
Note over StateMachine,GitHub: State: LINT
StateMachine->>StateMachine: Check dependencies: [INIT] ✓
StateMachine->>Activities: run_megalinter(statedata)
Activities->>GitHub: Trigger workflow
GitHub-->>Activities: Lint results
Activities-->>StateMachine: Store in statedata['lint']
alt Lint errors found & auto_fix_lint enabled
StateMachine->>StateMachine: Inject AUTO_FIX state<br/>BUILD depends on AUTO_FIX now
StateMachine->>StateMachine: Transition to AUTO_FIX
StateMachine->>Activities: get_files_with_lint_errors
StateMachine->>Activities: analyze_lint_failures_with_claude
Activities->>Claude: Analyze errors
Claude-->>Activities: Return fixes
StateMachine->>Activities: mcp_create_branch
StateMachine->>Activities: mcp_push_files
StateMachine->>Activities: create_pull_request_with_fixes
Activities->>GitHub: Create PR
StateMachine->>StateMachine: Store in statedata['auto_fix']
end
alt fail_on_lint_errors = true & errors exist
StateMachine->>StateMachine: Raise ApplicationError
StateMachine-->>CLI: Exit with failure
end
end
rect rgb(240, 255, 240)
Note over StateMachine,GitHub: State: BUILD
StateMachine->>StateMachine: Check dependencies: [AUTO_FIX or LINT] ✓
StateMachine->>Activities: run_build_image(statedata)
Activities->>GitHub: Trigger build workflow
GitHub-->>Activities: Build complete with digest
Activities-->>StateMachine: Store in statedata['build']
alt Build failed
StateMachine->>StateMachine: Inject BUILD_FAILURE state
StateMachine->>Activities: create_failure_issue
Activities->>GitHub: Create issue
StateMachine->>StateMachine: Raise ApplicationError
end
end
rect rgb(240, 240, 255)
Note over StateMachine,GitHub: State: PARALLEL_SBOM_SIGN
StateMachine->>StateMachine: Check dependencies: [BUILD] ✓
par SBOM Branch
StateMachine->>Activities: run_generate_sbom(statedata)
Activities->>GitHub: Generate SBOM
StateMachine->>Activities: run_scan_sbom(statedata)
Activities->>GitHub: Scan vulnerabilities
Activities-->>StateMachine: Store in statedata['scan_sbom']
and Sign Branch
StateMachine->>Activities: run_sign_image(statedata)
Activities->>GitHub: Cosign keyless signing
Activities-->>StateMachine: Store in statedata['sign_image']
end
alt Critical/High vulnerabilities found
StateMachine->>StateMachine: Inject VULNERABILITY_REMEDIATION state<br/>ATTEST depends on it now
StateMachine->>StateMachine: Transition to VULNERABILITY_REMEDIATION
StateMachine->>Activities: create_vulnerability_issue
Activities->>GitHub: Create security issue
StateMachine->>StateMachine: Store in statedata['vulnerability_remediation']
alt fail_on_vulnerabilities = true
StateMachine->>StateMachine: Raise ApplicationError
end
end
end
rect rgb(255, 255, 240)
Note over StateMachine,GitHub: State: ATTEST
StateMachine->>StateMachine: Check dependencies: [PARALLEL or VULN_REMEDIATION] ✓
StateMachine->>Activities: run_attest_sbom(statedata)
Activities->>GitHub: Attach SBOM attestation
Activities-->>StateMachine: Store in statedata['attest']
end
rect rgb(240, 255, 255)
Note over StateMachine,GitHub: State: VERIFY
StateMachine->>StateMachine: Check dependencies: [ATTEST] ✓
StateMachine->>Activities: run_verify_signatures(statedata)
Activities->>GitHub: Verify signatures & attestations
Activities-->>StateMachine: Store in statedata['verify']
alt Verification failed
StateMachine->>StateMachine: Inject VERIFY_FAILURE state
StateMachine->>Activities: create_failure_issue
Activities->>GitHub: Create compliance issue
StateMachine->>StateMachine: Raise ApplicationError
end
end
rect rgb(255, 240, 255)
Note over StateMachine,GitHub: State: UPDATE_STATUS
StateMachine->>StateMachine: Check dependencies: [VERIFY] ✓
opt update_commit_status in preset
StateMachine->>Activities: update_commit_status(statedata)
Activities->>GitHub: Update commit status
end
StateMachine->>StateMachine: Transition to DONE
end
StateMachine-->>CLI: Success (SLSA Level 3 ✅)
Components
System Architecture
graph TB
CLI[CLI Command] --> Temporal[Temporal Client]
Temporal --> Worker[Temporal Worker]
Worker --> Orchestrator[SLSABuildPipeline<br/>Workflow]
Orchestrator --> StateMachine[State Machine<br/>Dependency Graph]
StateMachine --> Activities[Activities]
Activities --> MCP[GitHub MCP Manager]
Activities --> API[GitHub API Client]
Activities --> Claude[Claude AI Activity]
MCP -->|Branch/Files/PRs| GitHub[GitHub Repository]
API -->|Workflows/Status/Artifacts| GitHub
Claude -->|Lint Analysis| Anthropic[Anthropic API]
GitHub -->|Workflows| Actions[GitHub Actions]
Actions -->|Lint| Lint[00-megalinter]
Actions -->|Build| Build[01-build-image]
Actions -->|SBOM| SBOM[02-generate-sbom]
Actions -->|Scan| Scan[03-scan-sbom]
Actions -->|Sign| Sign[04-sign-image]
Actions -->|Attest| Attest[05-attest-sbom]
Actions -->|Verify| Verify[06-verify-signatures]
style StateMachine fill:#FFE4B5
style Activities fill:#E6E6FA
style MCP fill:#90EE90
style API fill:#FFB6C1
style Claude fill:#87CEEB
Core Components
1. Orchestrator (orchestrator.py)
- SLSABuildPipeline Workflow: Main Temporal workflow class
- State Machine Dispatcher: Routes to state handlers via
_dispatch_state() - Dependency Manager: Manages state dependencies and transitions
- Data Manager: Maintains centralized
statedatadictionary
Key Methods:
run()- Entry point, initializes state dependencies_dispatch_state()- Routes to appropriate state handler_get_next_state()- Resolves next state via dependency graph_step_*()- Individual state handlers (e.g.,_step_build())
2. Activities (activities.py)
15 activities organized into 5 categories:
MCP Activities (4):
mcp_create_branch- Create Git branchesmcp_push_files- Push file changesget_files_with_lint_errors- Extract files with errorscreate_pull_request_with_fixes- Create PRs with fixes
Issue Management (2):
create_vulnerability_issue- Create security issuescreate_failure_issue- Create pipeline failure issues
AI Integration (1):
analyze_lint_failures_with_claude- AI-powered code analysis
Workflow Execution (7):
run_megalinter- Execute lintingrun_build_image- Build containerrun_generate_sbom- Generate SBOMrun_scan_sbom- Scan for vulnerabilitiesrun_sign_image- Sign image with Cosignrun_attest_sbom- Attach SBOM attestationrun_verify_signatures- Verify signatures
Status Management (1):
update_commit_status- Update GitHub commit status
3. Temporal Worker (temporal.py)
- Connects to Temporal server
- Registers workflow and all 15 activities
- Handles graceful shutdown of MCP connections
4. Presets (presets.py)
Three golden path presets with workflow configurations:
- minimal: Fast iteration (5 min)
- standard: Full SLSA Level 3 (15-20 min)
- skip_linting: Hotfix without linting (12-15 min)
5. GitHub MCP Manager
Singleton manager for GitHub MCP server connections:
- Manages single MCP connection per worker
- Provides async context management
- Handles cleanup on shutdown
SLSA Level 3 Compliance
✅ Provenance (Docker buildx)
✅ Signed provenance (Cosign keyless with OIDC)
✅ Immutable image digest
✅ SBOM included & attested (CycloneDX)
✅ Signature verification
✅ Full audit trail (Temporal + GitHub Actions)
✅ Transparency via Rekor/Sigstore
Advanced Usage
Temporal UI: http://localhost:8233
Start Worker:
slsa-pipeline worker
Trigger Workflow:
slsa-pipeline run \
--preset standard \
--repo-owner ortelius \
--repo-name ms-dep-pkg-r \
--image-name ortelius/ms-dep-pkg-r \
--image-tag main-v10.0.1715-gcf5542 \
--registry quay.io \
--auto-fix-lint
Learn More
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ortelius_slsa_pipeline-1.0.0.tar.gz.
File metadata
- Download URL: ortelius_slsa_pipeline-1.0.0.tar.gz
- Upload date:
- Size: 40.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
472afd633aa31595f69ff041bbe4221fee445ea00505e0460227a9ffdc987023
|
|
| MD5 |
a3fe4275e240d7a4767d07c4b4809093
|
|
| BLAKE2b-256 |
d8be34793bd4259fde9abadf5b116e27d6a3f79d148daffa078c8e2ff22fd31f
|
File details
Details for the file ortelius_slsa_pipeline-1.0.0-py3-none-any.whl.
File metadata
- Download URL: ortelius_slsa_pipeline-1.0.0-py3-none-any.whl
- Upload date:
- Size: 36.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bf4b9900e752050b82650669d31a433a26602453f554da4428b98050437142f2
|
|
| MD5 |
4ed7e51f39cfaa7bcf504e772cc30b5f
|
|
| BLAKE2b-256 |
3f8cc29028f7c58f88fb0712f3ff173176ab3f2ef697d2f25c55af898eb25b37
|