stratumoss 0.5.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. stratumoss-0.5.2/.dockerignore +8 -0
  2. stratumoss-0.5.2/.env.example +76 -0
  3. stratumoss-0.5.2/.github/CODEOWNERS +3 -0
  4. stratumoss-0.5.2/.github/ISSUE_TEMPLATE/bug_report.md +35 -0
  5. stratumoss-0.5.2/.github/ISSUE_TEMPLATE/feature_request.md +21 -0
  6. stratumoss-0.5.2/.github/PULL_REQUEST_TEMPLATE.md +27 -0
  7. stratumoss-0.5.2/.github/dependabot.yml +17 -0
  8. stratumoss-0.5.2/.github/workflows/ci.yml +157 -0
  9. stratumoss-0.5.2/.github/workflows/dco.yml +32 -0
  10. stratumoss-0.5.2/.github/workflows/refresh-amis.yml +54 -0
  11. stratumoss-0.5.2/.github/workflows/release.yml +102 -0
  12. stratumoss-0.5.2/.github/workflows/weekly-image-refresh.yml +48 -0
  13. stratumoss-0.5.2/.gitignore +57 -0
  14. stratumoss-0.5.2/.python-version +1 -0
  15. stratumoss-0.5.2/CHANGELOG.md +291 -0
  16. stratumoss-0.5.2/CODE_OF_CONDUCT.md +61 -0
  17. stratumoss-0.5.2/CONTRIBUTING.md +466 -0
  18. stratumoss-0.5.2/Dockerfile +44 -0
  19. stratumoss-0.5.2/LICENSE +170 -0
  20. stratumoss-0.5.2/PKG-INFO +722 -0
  21. stratumoss-0.5.2/README.md +643 -0
  22. stratumoss-0.5.2/ROADMAP.md +88 -0
  23. stratumoss-0.5.2/SECURITY.md +48 -0
  24. stratumoss-0.5.2/ansible/README.md +79 -0
  25. stratumoss-0.5.2/ansible/site.yml +55 -0
  26. stratumoss-0.5.2/blueprints/CONTRIBUTING.md +293 -0
  27. stratumoss-0.5.2/blueprints/README.md +98 -0
  28. stratumoss-0.5.2/blueprints/alma/9/cis-l1-aws.yaml +84 -0
  29. stratumoss-0.5.2/blueprints/amazon-linux/2023/cis-l1-aws.yaml +109 -0
  30. stratumoss-0.5.2/blueprints/debian/12/cis-l1-aws.yaml +84 -0
  31. stratumoss-0.5.2/blueprints/debian/12/cis-l1-digitalocean.yaml +69 -0
  32. stratumoss-0.5.2/blueprints/debian/12/cis-l1-gcp.yaml +71 -0
  33. stratumoss-0.5.2/blueprints/generic/hardening-blueprint.yaml +85 -0
  34. stratumoss-0.5.2/blueprints/index.json +20 -0
  35. stratumoss-0.5.2/blueprints/rocky/9/cis-l1-aws.yaml +90 -0
  36. stratumoss-0.5.2/blueprints/rocky/9/cis-l1-azure.yaml +78 -0
  37. stratumoss-0.5.2/blueprints/rocky/9/cis-l1-digitalocean.yaml +76 -0
  38. stratumoss-0.5.2/blueprints/rocky/9/cis-l1-gcp.yaml +81 -0
  39. stratumoss-0.5.2/blueprints/rocky/9/cis-l1-linode.yaml +73 -0
  40. stratumoss-0.5.2/blueprints/rocky/9/cis-l1-proxmox.yaml +79 -0
  41. stratumoss-0.5.2/blueprints/ubuntu/22.04/cis-l1-aws.yaml +120 -0
  42. stratumoss-0.5.2/blueprints/ubuntu/22.04/cis-l1-azure.yaml +84 -0
  43. stratumoss-0.5.2/blueprints/ubuntu/22.04/cis-l1-digitalocean.yaml +75 -0
  44. stratumoss-0.5.2/blueprints/ubuntu/22.04/cis-l1-gcp.yaml +87 -0
  45. stratumoss-0.5.2/blueprints/ubuntu/22.04/cis-l1-linode.yaml +82 -0
  46. stratumoss-0.5.2/blueprints/ubuntu/22.04/cis-l1-proxmox.yaml +89 -0
  47. stratumoss-0.5.2/deploy/aws/README.md +64 -0
  48. stratumoss-0.5.2/deploy/aws/stratum-builder-role.yaml +128 -0
  49. stratumoss-0.5.2/deploy/aws/stratum-scanner-role.yaml +117 -0
  50. stratumoss-0.5.2/deploy/azure/README.md +45 -0
  51. stratumoss-0.5.2/deploy/azure/stratum-builder-role.json +151 -0
  52. stratumoss-0.5.2/deploy/azure/stratum-scanner-role.json +139 -0
  53. stratumoss-0.5.2/deploy/gcp/README.md +51 -0
  54. stratumoss-0.5.2/deploy/gcp/builder/onboard.sh +85 -0
  55. stratumoss-0.5.2/deploy/gcp/builder/stratum-builder-role.yaml +35 -0
  56. stratumoss-0.5.2/deploy/gcp/scanner/onboard.sh +76 -0
  57. stratumoss-0.5.2/deploy/gcp/scanner/stratum-scanner-role.yaml +29 -0
  58. stratumoss-0.5.2/docker-compose.yml +58 -0
  59. stratumoss-0.5.2/docs/api.md +74 -0
  60. stratumoss-0.5.2/docs/assets/cloud-onboarding.svg +41 -0
  61. stratumoss-0.5.2/docs/assets/compliance-report.svg +28 -0
  62. stratumoss-0.5.2/docs/assets/stratum-dashboard.svg +51 -0
  63. stratumoss-0.5.2/docs/cloud-onboarding.md +84 -0
  64. stratumoss-0.5.2/docs/pipeline.md +647 -0
  65. stratumoss-0.5.2/docs/stratum-blueprints-template.yaml +275 -0
  66. stratumoss-0.5.2/docs/test_plan.md +373 -0
  67. stratumoss-0.5.2/docs/user-guide.md +44 -0
  68. stratumoss-0.5.2/docs/ux-flow-cis-l2-amazon-linux-2023.md +672 -0
  69. stratumoss-0.5.2/input.css +3 -0
  70. stratumoss-0.5.2/plugins/catalog/azure.py +525 -0
  71. stratumoss-0.5.2/plugins/catalog/digitalocean.py +523 -0
  72. stratumoss-0.5.2/plugins/catalog/gcp.py +563 -0
  73. stratumoss-0.5.2/plugins/catalog/index.json +93 -0
  74. stratumoss-0.5.2/plugins/catalog/linode.py +463 -0
  75. stratumoss-0.5.2/plugins/catalog/proxmox.py +487 -0
  76. stratumoss-0.5.2/plugins/providers/README.md +49 -0
  77. stratumoss-0.5.2/plugins/providers/_provider_utils.py +905 -0
  78. stratumoss-0.5.2/plugins/providers/_qemu_utils.py +378 -0
  79. stratumoss-0.5.2/plugins/providers/aws.py +749 -0
  80. stratumoss-0.5.2/plugins/providers/azure.py +501 -0
  81. stratumoss-0.5.2/plugins/providers/digitalocean.py +464 -0
  82. stratumoss-0.5.2/plugins/providers/example_local.py +220 -0
  83. stratumoss-0.5.2/plugins/providers/gcp.py +579 -0
  84. stratumoss-0.5.2/plugins/providers/kvm.py +277 -0
  85. stratumoss-0.5.2/plugins/providers/linode.py +440 -0
  86. stratumoss-0.5.2/plugins/providers/proxmox.py +470 -0
  87. stratumoss-0.5.2/profiles/examples/ubuntu22_cis_l1.yaml +64 -0
  88. stratumoss-0.5.2/profiles/templates/alma9-cis-l1-aws.yaml +84 -0
  89. stratumoss-0.5.2/profiles/templates/amazon-linux-2023-cis-l1-aws.yaml +109 -0
  90. stratumoss-0.5.2/profiles/templates/debian12-cis-l1-aws.yaml +84 -0
  91. stratumoss-0.5.2/profiles/templates/debian12-cis-l1-digitalocean.yaml +69 -0
  92. stratumoss-0.5.2/profiles/templates/debian12-cis-l1-gcp.yaml +71 -0
  93. stratumoss-0.5.2/profiles/templates/generic-hardening-blueprint.yaml +85 -0
  94. stratumoss-0.5.2/profiles/templates/rocky9-cis-l1-aws.yaml +90 -0
  95. stratumoss-0.5.2/profiles/templates/rocky9-cis-l1-azure.yaml +78 -0
  96. stratumoss-0.5.2/profiles/templates/rocky9-cis-l1-digitalocean.yaml +76 -0
  97. stratumoss-0.5.2/profiles/templates/rocky9-cis-l1-gcp.yaml +81 -0
  98. stratumoss-0.5.2/profiles/templates/rocky9-cis-l1-linode.yaml +73 -0
  99. stratumoss-0.5.2/profiles/templates/rocky9-cis-l1-proxmox.yaml +79 -0
  100. stratumoss-0.5.2/profiles/templates/ubuntu22-cis-l1-aws.yaml +120 -0
  101. stratumoss-0.5.2/profiles/templates/ubuntu22-cis-l1-azure.yaml +84 -0
  102. stratumoss-0.5.2/profiles/templates/ubuntu22-cis-l1-digitalocean.yaml +75 -0
  103. stratumoss-0.5.2/profiles/templates/ubuntu22-cis-l1-gcp.yaml +87 -0
  104. stratumoss-0.5.2/profiles/templates/ubuntu22-cis-l1-linode.yaml +82 -0
  105. stratumoss-0.5.2/profiles/templates/ubuntu22-cis-l1-proxmox.yaml +89 -0
  106. stratumoss-0.5.2/pyproject.toml +119 -0
  107. stratumoss-0.5.2/scripts/refresh_ami_catalog.py +110 -0
  108. stratumoss-0.5.2/scripts/trigger_official_builds.py +161 -0
  109. stratumoss-0.5.2/stratum/__init__.py +5 -0
  110. stratumoss-0.5.2/stratum/api/__init__.py +2 -0
  111. stratumoss-0.5.2/stratum/api/agent.py +105 -0
  112. stratumoss-0.5.2/stratum/api/api_keys.py +37 -0
  113. stratumoss-0.5.2/stratum/api/auditor.py +353 -0
  114. stratumoss-0.5.2/stratum/api/blueprints.py +284 -0
  115. stratumoss-0.5.2/stratum/api/builder.py +815 -0
  116. stratumoss-0.5.2/stratum/api/integrations.py +594 -0
  117. stratumoss-0.5.2/stratum/api/pipeline.py +263 -0
  118. stratumoss-0.5.2/stratum/api/plugins.py +190 -0
  119. stratumoss-0.5.2/stratum/api/registry.py +37 -0
  120. stratumoss-0.5.2/stratum/api/ui.py +518 -0
  121. stratumoss-0.5.2/stratum/api/webhooks.py +76 -0
  122. stratumoss-0.5.2/stratum/config.py +56 -0
  123. stratumoss-0.5.2/stratum/core/__init__.py +2 -0
  124. stratumoss-0.5.2/stratum/core/agent.py +591 -0
  125. stratumoss-0.5.2/stratum/core/api_keys.py +79 -0
  126. stratumoss-0.5.2/stratum/core/auditor.py +356 -0
  127. stratumoss-0.5.2/stratum/core/auth.py +98 -0
  128. stratumoss-0.5.2/stratum/core/blueprint.py +201 -0
  129. stratumoss-0.5.2/stratum/core/builder.py +203 -0
  130. stratumoss-0.5.2/stratum/core/llm/__init__.py +14 -0
  131. stratumoss-0.5.2/stratum/core/llm/anthropic_backend.py +73 -0
  132. stratumoss-0.5.2/stratum/core/llm/base.py +56 -0
  133. stratumoss-0.5.2/stratum/core/llm/bedrock_backend.py +195 -0
  134. stratumoss-0.5.2/stratum/core/llm/factory.py +124 -0
  135. stratumoss-0.5.2/stratum/core/llm/openai_backend.py +284 -0
  136. stratumoss-0.5.2/stratum/core/notifications.py +152 -0
  137. stratumoss-0.5.2/stratum/core/os_catalog.py +1818 -0
  138. stratumoss-0.5.2/stratum/core/parser.py +150 -0
  139. stratumoss-0.5.2/stratum/core/playbook_gen.py +412 -0
  140. stratumoss-0.5.2/stratum/core/registry.py +238 -0
  141. stratumoss-0.5.2/stratum/core/report.py +407 -0
  142. stratumoss-0.5.2/stratum/main.py +127 -0
  143. stratumoss-0.5.2/stratum/openscap/__init__.py +2 -0
  144. stratumoss-0.5.2/stratum/openscap/parser.py +115 -0
  145. stratumoss-0.5.2/stratum/openscap/scanner.py +94 -0
  146. stratumoss-0.5.2/stratum/paths.py +20 -0
  147. stratumoss-0.5.2/stratum/plugins/__init__.py +2 -0
  148. stratumoss-0.5.2/stratum/plugins/base_provider.py +52 -0
  149. stratumoss-0.5.2/stratum/plugins/loader.py +145 -0
  150. stratumoss-0.5.2/stratum/plugins/registry.py +57 -0
  151. stratumoss-0.5.2/stratum/plugins/subprocess_provider.py +184 -0
  152. stratumoss-0.5.2/stratum/static/css/tailwind.css +2075 -0
  153. stratumoss-0.5.2/stratum/static/js/htmx.min.js +1 -0
  154. stratumoss-0.5.2/stratum/templates/agent/index.html +366 -0
  155. stratumoss-0.5.2/stratum/templates/auditor/compare.html +110 -0
  156. stratumoss-0.5.2/stratum/templates/auditor/history.html +104 -0
  157. stratumoss-0.5.2/stratum/templates/auditor/index.html +60 -0
  158. stratumoss-0.5.2/stratum/templates/auditor/report.html +298 -0
  159. stratumoss-0.5.2/stratum/templates/auditor/results.html +100 -0
  160. stratumoss-0.5.2/stratum/templates/auditor/scan_image.html +110 -0
  161. stratumoss-0.5.2/stratum/templates/auditor/scan_image_results.html +196 -0
  162. stratumoss-0.5.2/stratum/templates/auditor/scanner/steps/step1_target.html +209 -0
  163. stratumoss-0.5.2/stratum/templates/auditor/scanner/steps/step2_benchmark.html +172 -0
  164. stratumoss-0.5.2/stratum/templates/auditor/scanner/steps/step3_review.html +136 -0
  165. stratumoss-0.5.2/stratum/templates/auditor/scanner/wizard.html +114 -0
  166. stratumoss-0.5.2/stratum/templates/base.html +156 -0
  167. stratumoss-0.5.2/stratum/templates/blueprints/index.html +314 -0
  168. stratumoss-0.5.2/stratum/templates/blueprints/studio.html +245 -0
  169. stratumoss-0.5.2/stratum/templates/builder/index.html +64 -0
  170. stratumoss-0.5.2/stratum/templates/builder/run.html +27 -0
  171. stratumoss-0.5.2/stratum/templates/builder/steps/step1_os.html +178 -0
  172. stratumoss-0.5.2/stratum/templates/builder/steps/step2_storage.html +512 -0
  173. stratumoss-0.5.2/stratum/templates/builder/steps/step3_users.html +224 -0
  174. stratumoss-0.5.2/stratum/templates/builder/steps/step4_hardening.html +237 -0
  175. stratumoss-0.5.2/stratum/templates/builder/steps/step5_review.html +335 -0
  176. stratumoss-0.5.2/stratum/templates/builder/wizard.html +145 -0
  177. stratumoss-0.5.2/stratum/templates/index.html +183 -0
  178. stratumoss-0.5.2/stratum/templates/integrations/index.html +85 -0
  179. stratumoss-0.5.2/stratum/templates/integrations/partials/available_plugins.html +34 -0
  180. stratumoss-0.5.2/stratum/templates/integrations/partials/aws.html +244 -0
  181. stratumoss-0.5.2/stratum/templates/integrations/partials/azure.html +118 -0
  182. stratumoss-0.5.2/stratum/templates/integrations/partials/gcp.html +106 -0
  183. stratumoss-0.5.2/stratum/templates/integrations/partials/generic.html +111 -0
  184. stratumoss-0.5.2/stratum/templates/integrations/partials/install_success.html +7 -0
  185. stratumoss-0.5.2/stratum/templates/integrations/partials/remove_success.html +7 -0
  186. stratumoss-0.5.2/stratum/templates/partials/blueprint_yaml.html +10 -0
  187. stratumoss-0.5.2/stratum/templates/partials/job_status.html +143 -0
  188. stratumoss-0.5.2/stratum/templates/partials/provider_fields.html +36 -0
  189. stratumoss-0.5.2/stratum/templates/partials/report_table.html +59 -0
  190. stratumoss-0.5.2/stratum/templates/settings/api_keys.html +159 -0
  191. stratumoss-0.5.2/stratum/templates/settings/webhooks.html +216 -0
  192. stratumoss-0.5.2/tailwind.config.js +19 -0
  193. stratumoss-0.5.2/tests/__init__.py +2 -0
  194. stratumoss-0.5.2/tests/api/__init__.py +1 -0
  195. stratumoss-0.5.2/tests/api/conftest.py +169 -0
  196. stratumoss-0.5.2/tests/api/test_api_agent_sse.py +152 -0
  197. stratumoss-0.5.2/tests/api/test_api_api_keys.py +109 -0
  198. stratumoss-0.5.2/tests/api/test_api_auditor.py +301 -0
  199. stratumoss-0.5.2/tests/api/test_api_blueprints.py +313 -0
  200. stratumoss-0.5.2/tests/api/test_api_blueprints_extended.py +274 -0
  201. stratumoss-0.5.2/tests/api/test_api_builder.py +557 -0
  202. stratumoss-0.5.2/tests/api/test_api_coverage_gaps.py +383 -0
  203. stratumoss-0.5.2/tests/api/test_api_integrations.py +956 -0
  204. stratumoss-0.5.2/tests/api/test_api_pipeline.py +537 -0
  205. stratumoss-0.5.2/tests/api/test_api_plugins.py +142 -0
  206. stratumoss-0.5.2/tests/api/test_api_plugins_auditor_pipeline.py +291 -0
  207. stratumoss-0.5.2/tests/api/test_api_registry.py +114 -0
  208. stratumoss-0.5.2/tests/api/test_api_ui.py +261 -0
  209. stratumoss-0.5.2/tests/api/test_api_webhooks.py +225 -0
  210. stratumoss-0.5.2/tests/api/test_edge_cases.py +373 -0
  211. stratumoss-0.5.2/tests/conftest.py +18 -0
  212. stratumoss-0.5.2/tests/integration/__init__.py +2 -0
  213. stratumoss-0.5.2/tests/integration/conftest.py +139 -0
  214. stratumoss-0.5.2/tests/integration/test_aws_e2e.py +473 -0
  215. stratumoss-0.5.2/tests/providers/__init__.py +0 -0
  216. stratumoss-0.5.2/tests/providers/test_provider_aws.py +307 -0
  217. stratumoss-0.5.2/tests/providers/test_provider_azure.py +214 -0
  218. stratumoss-0.5.2/tests/providers/test_provider_contract.py +245 -0
  219. stratumoss-0.5.2/tests/providers/test_provider_digitalocean.py +202 -0
  220. stratumoss-0.5.2/tests/providers/test_provider_gcp.py +255 -0
  221. stratumoss-0.5.2/tests/providers/test_provider_kvm.py +242 -0
  222. stratumoss-0.5.2/tests/providers/test_provider_linode.py +220 -0
  223. stratumoss-0.5.2/tests/providers/test_provider_proxmox.py +283 -0
  224. stratumoss-0.5.2/tests/providers/test_provider_utils.py +572 -0
  225. stratumoss-0.5.2/tests/providers/test_qemu_utils.py +346 -0
  226. stratumoss-0.5.2/tests/security/__init__.py +0 -0
  227. stratumoss-0.5.2/tests/security/test_api_key_security.py +75 -0
  228. stratumoss-0.5.2/tests/security/test_blueprint_security.py +125 -0
  229. stratumoss-0.5.2/tests/security/test_webhook_security.py +145 -0
  230. stratumoss-0.5.2/tests/test_agent_core.py +773 -0
  231. stratumoss-0.5.2/tests/test_api_keys.py +154 -0
  232. stratumoss-0.5.2/tests/test_auditor_core.py +541 -0
  233. stratumoss-0.5.2/tests/test_blueprint.py +88 -0
  234. stratumoss-0.5.2/tests/test_cloud_onboarding_templates.py +89 -0
  235. stratumoss-0.5.2/tests/test_core_builder.py +280 -0
  236. stratumoss-0.5.2/tests/test_credential_store.py +211 -0
  237. stratumoss-0.5.2/tests/test_final_gaps.py +272 -0
  238. stratumoss-0.5.2/tests/test_gaps.py +398 -0
  239. stratumoss-0.5.2/tests/test_llm_backends.py +283 -0
  240. stratumoss-0.5.2/tests/test_llm_backends_extended.py +726 -0
  241. stratumoss-0.5.2/tests/test_notifications.py +261 -0
  242. stratumoss-0.5.2/tests/test_openai_backend_toolcalls.py +368 -0
  243. stratumoss-0.5.2/tests/test_openscap_parser.py +158 -0
  244. stratumoss-0.5.2/tests/test_packaging_paths.py +213 -0
  245. stratumoss-0.5.2/tests/test_persistence.py +177 -0
  246. stratumoss-0.5.2/tests/test_pipeline_logic.py +218 -0
  247. stratumoss-0.5.2/tests/test_playbook_gen.py +370 -0
  248. stratumoss-0.5.2/tests/test_plugin_loader.py +226 -0
  249. stratumoss-0.5.2/tests/test_plugins_extended.py +299 -0
  250. stratumoss-0.5.2/tests/test_registry.py +333 -0
  251. stratumoss-0.5.2/tests/test_regression.py +136 -0
  252. stratumoss-0.5.2/tests/test_remaining_gaps.py +466 -0
  253. stratumoss-0.5.2/tests/test_report.py +514 -0
  254. stratumoss-0.5.2/tests/test_sarif.py +215 -0
  255. stratumoss-0.5.2/tests/test_scanner.py +139 -0
  256. stratumoss-0.5.2/tests/test_scap_parser.py +168 -0
  257. stratumoss-0.5.2/tests/test_subprocess_provider.py +296 -0
  258. stratumoss-0.5.2/tests/ui/__init__.py +0 -0
  259. stratumoss-0.5.2/tests/ui/test_pages.py +369 -0
  260. stratumoss-0.5.2/update_templates.py +39 -0
@@ -0,0 +1,8 @@
1
+ .git
2
+ .venv
3
+ venv
4
+ __pycache__
5
+ *.pyc
6
+ tests/
7
+ .env
8
+ .pytest_cache
@@ -0,0 +1,76 @@
1
+ # Stratum — environment variable reference
2
+ # Copy to .env and fill in the values you need.
3
+ # Stratum reads this file automatically on startup (via python-dotenv).
4
+
5
+ # ---------------------------------------------------------------------------
6
+ # Core
7
+ # ---------------------------------------------------------------------------
8
+
9
+ # Passphrase for the credential encryption key.
10
+ # If unset, a random key is auto-generated and stored in data/.stratum_key.
11
+ # Set this to keep credentials accessible across container rebuilds.
12
+ # STRATUM_SECRET_KEY=change-me-to-a-strong-random-passphrase
13
+
14
+ # Admin token — required to log in to the UI and API (HTTP Basic Auth, any
15
+ # username, this as the password). If unset, a random token is generated and
16
+ # saved to data/.admin_token on first startup (check the container logs for it).
17
+ # Set this to keep a stable login across restarts.
18
+ # STRATUM_ADMIN_TOKEN=change-me-to-a-strong-random-token
19
+
20
+ # Require manual confirmation before the AI Builder agent provisions real
21
+ # cloud infrastructure (default: true). Set to false to let the agent build
22
+ # autonomously without a human clicking "Build" in the UI first.
23
+ # STRATUM_AGENT_REQUIRE_CONFIRMATION=true
24
+
25
+ # Override default storage paths (optional)
26
+ # DATA_DIR=data
27
+ # PLUGINS_DIR=plugins/providers
28
+ # PROFILES_DIR=profiles
29
+
30
+ # ---------------------------------------------------------------------------
31
+ # AI Builder — pick ONE backend and uncomment the relevant block
32
+ # ---------------------------------------------------------------------------
33
+
34
+ # --- Anthropic (default) ---
35
+ # STRATUM_LLM_PROVIDER=anthropic
36
+ # STRATUM_LLM_MODEL=claude-opus-4-6
37
+ # ANTHROPIC_API_KEY=sk-ant-...
38
+
39
+ # --- OpenAI or any OpenAI-compatible endpoint ---
40
+ # Works with Groq, Together AI, Fireworks, vLLM, LiteLLM, etc.
41
+ # Requires: uv add openai
42
+ # STRATUM_LLM_PROVIDER=openai
43
+ # STRATUM_LLM_MODEL=gpt-4o
44
+ # STRATUM_LLM_API_KEY=sk-...
45
+ # STRATUM_LLM_BASE_URL=https://api.groq.com/openai/v1
46
+
47
+ # --- Ollama (local, no API key) ---
48
+ # Run open-weight models locally. Requires Ollama: https://ollama.com
49
+ # Requires: uv add openai (Ollama exposes an OpenAI-compatible endpoint)
50
+ # STRATUM_LLM_PROVIDER=ollama
51
+ # STRATUM_LLM_MODEL=llama3.3:70b
52
+ # STRATUM_LLM_BASE_URL=http://localhost:11434/v1
53
+
54
+ # --- AWS Bedrock ---
55
+ # Reuses your existing AWS credentials. No separate API key needed.
56
+ # Requires: uv add boto3 (or uv sync --extra llm-bedrock)
57
+ # Needs bedrock:InvokeModelWithResponseStream IAM permission.
58
+ # STRATUM_LLM_PROVIDER=bedrock
59
+ # STRATUM_LLM_MODEL=us.anthropic.claude-opus-4-5-20251101-v1:0
60
+
61
+ # Disable Claude extended thinking (Anthropic/Bedrock only)
62
+ # STRATUM_LLM_THINKING=1
63
+
64
+ # ---------------------------------------------------------------------------
65
+ # Blueprint Registry
66
+ # ---------------------------------------------------------------------------
67
+
68
+ # Private S3 blueprint store (optional)
69
+ # BLUEPRINT_STORE_S3_BUCKET=my-company-blueprints
70
+ # BLUEPRINT_STORE_S3_PREFIX=stratum/
71
+ # BLUEPRINT_STORE_S3_REGION=us-east-1
72
+
73
+ # ---------------------------------------------------------------------------
74
+ # Debug
75
+ # ---------------------------------------------------------------------------
76
+ # DEBUG=false
@@ -0,0 +1,3 @@
1
+ # Default owner for everything in the repo.
2
+ # PRs automatically request review from the maintainer.
3
+ * @rrskris
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: Bug report
3
+ about: Something in Stratum isn't working as expected
4
+ title: ""
5
+ labels: bug
6
+ assignees: ""
7
+ ---
8
+
9
+ **Describe the bug**
10
+ A clear description of what's broken.
11
+
12
+ **Blueprint / request**
13
+ The blueprint YAML (redact real credentials/AMI IDs if needed) or `curl`
14
+ request that triggers the issue.
15
+
16
+ ```yaml
17
+ # paste blueprint YAML here
18
+ ```
19
+
20
+ **Expected behavior**
21
+ What you expected to happen.
22
+
23
+ **Actual behavior**
24
+ What actually happened — include the full error message / stack trace / API
25
+ response if there is one.
26
+
27
+ **Environment**
28
+ - Stratum version (`pyproject.toml` version or commit hash):
29
+ - Deployment: Docker Compose / local `uv run` / other:
30
+ - Cloud provider(s) involved, if any:
31
+ - OS/target image:
32
+
33
+ **Additional context**
34
+ Anything else that might help (relevant log lines from `docker compose logs`,
35
+ screenshots of the UI, etc.).
@@ -0,0 +1,21 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for Stratum
4
+ title: ""
5
+ labels: enhancement
6
+ assignees: ""
7
+ ---
8
+
9
+ **What problem does this solve?**
10
+ Describe the gap or pain point — e.g. a cloud provider, OS, or workflow
11
+ Stratum doesn't support yet.
12
+
13
+ **Proposed solution**
14
+ What would you like to happen? If it touches the blueprint schema, sketch the
15
+ YAML shape you'd expect.
16
+
17
+ **Alternatives considered**
18
+ Any workarounds you're using today, or other tools that solve this.
19
+
20
+ **Additional context**
21
+ Links, references, or examples (e.g. a CIS/STIG control, a provider API doc).
@@ -0,0 +1,27 @@
1
+ ## What does this PR do?
2
+
3
+ <!-- One or two sentences. -->
4
+
5
+ ## Why
6
+
7
+ <!-- The problem or gap this addresses. -->
8
+
9
+ ## Testing
10
+
11
+ <!-- How did you verify this? -->
12
+ - [ ] `uv run pytest` passes locally
13
+ - [ ] `uv run ruff check .` and `uv run ruff format --check .` pass
14
+ - [ ] Added/updated tests for the change (see `docs/test_plan.md` for the
15
+ project's TDD conventions)
16
+ - [ ] If this touches a cloud provider: ran against a real provider, or
17
+ explained why that isn't practical for this change
18
+ - [ ] If this adds or changes a blueprint: the "Validate community blueprints"
19
+ check passes (schema + `blueprints/index.json` consistency)
20
+
21
+ ## Checklist
22
+
23
+ - [ ] I've read `CONTRIBUTING.md`
24
+ - [ ] This PR is scoped to one logical change
25
+ - [ ] I've updated `CHANGELOG.md` if this is user-visible
26
+ - [ ] All commits are signed off (`git commit -s`) per the
27
+ [DCO](https://developercertificate.org/)
@@ -0,0 +1,17 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "pip"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ groups:
8
+ minor-and-patch:
9
+ update-types: ["minor", "patch"]
10
+ - package-ecosystem: "github-actions"
11
+ directory: "/"
12
+ schedule:
13
+ interval: "weekly"
14
+ - package-ecosystem: "docker"
15
+ directory: "/"
16
+ schedule:
17
+ interval: "weekly"
@@ -0,0 +1,157 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: ["main", "develop"]
6
+ pull_request:
7
+
8
+ jobs:
9
+ lint:
10
+ name: Lint (ruff)
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: astral-sh/setup-uv@v5
15
+ with:
16
+ python-version: "3.11"
17
+ - run: uv sync --extra all-providers --group dev
18
+ - run: uv run ruff check .
19
+ - run: uv run ruff format --check .
20
+
21
+ test:
22
+ name: Tests (pytest)
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+ - uses: astral-sh/setup-uv@v5
27
+ with:
28
+ python-version: "3.11"
29
+ - run: uv sync --extra all-providers --group dev
30
+ - run: uv run pytest tests/ -v --tb=short
31
+
32
+ schema:
33
+ name: Validate blueprint YAML schemas
34
+ runs-on: ubuntu-latest
35
+ steps:
36
+ - uses: actions/checkout@v4
37
+ - uses: astral-sh/setup-uv@v5
38
+ with:
39
+ python-version: "3.11"
40
+ - run: uv sync
41
+ - name: Validate all profiles
42
+ run: |
43
+ uv run python - <<'EOF'
44
+ import sys
45
+ from pathlib import Path
46
+ from stratum.core.blueprint import ComplianceProfile
47
+ import yaml
48
+
49
+ errors = []
50
+ profiles_dir = Path("profiles")
51
+ yaml_files = list(profiles_dir.rglob("*.yaml")) + list(profiles_dir.rglob("*.yml"))
52
+ # Skip the generic template — it intentionally has null controls
53
+ skip = {"generic-hardening-blueprint.yaml"}
54
+
55
+ for p in sorted(yaml_files):
56
+ if p.name in skip:
57
+ print(f" SKIP {p}")
58
+ continue
59
+ try:
60
+ raw = yaml.safe_load(p.read_text())
61
+ if not isinstance(raw, dict):
62
+ errors.append(f" ERROR {p}: top-level is not a mapping")
63
+ continue
64
+ ComplianceProfile.model_validate(raw)
65
+ print(f" OK {p}")
66
+ except Exception as exc:
67
+ errors.append(f" ERROR {p}: {exc}")
68
+
69
+ if errors:
70
+ print("\nSchema validation failed:")
71
+ for e in errors:
72
+ print(e)
73
+ sys.exit(1)
74
+ else:
75
+ print(f"\nAll {len(yaml_files) - len(skip)} profiles validated successfully.")
76
+ EOF
77
+
78
+ validate-blueprints:
79
+ name: Validate community blueprints
80
+ runs-on: ubuntu-latest
81
+ steps:
82
+ - uses: actions/checkout@v4
83
+ - uses: astral-sh/setup-uv@v5
84
+ with:
85
+ python-version: "3.11"
86
+ - run: uv sync
87
+ - name: Validate blueprint schemas
88
+ run: |
89
+ uv run python - <<'EOF'
90
+ import sys
91
+ from pathlib import Path
92
+ from stratum.core.blueprint import ComplianceProfile
93
+ import yaml
94
+
95
+ errors = []
96
+ yaml_files = sorted(Path("blueprints").rglob("*.yaml"))
97
+
98
+ for p in yaml_files:
99
+ try:
100
+ raw = yaml.safe_load(p.read_text())
101
+ if not isinstance(raw, dict):
102
+ errors.append(f" ERROR {p}: top-level is not a mapping")
103
+ continue
104
+ ComplianceProfile.model_validate(raw)
105
+ print(f" OK {p}")
106
+ except Exception as exc:
107
+ errors.append(f" ERROR {p}: {exc}")
108
+
109
+ if errors:
110
+ print("\nBlueprint schema validation failed:")
111
+ for e in errors:
112
+ print(e)
113
+ sys.exit(1)
114
+ else:
115
+ print(f"\nAll {len(yaml_files)} blueprints validated successfully.")
116
+ EOF
117
+ - name: Check index.json consistency
118
+ run: |
119
+ uv run python - <<'EOF'
120
+ import json
121
+ import sys
122
+ from pathlib import Path
123
+
124
+ on_disk = {str(p.relative_to("blueprints")) for p in Path("blueprints").rglob("*.yaml")}
125
+ indexed = set(json.loads(Path("blueprints/index.json").read_text()))
126
+
127
+ missing_from_index = sorted(on_disk - indexed)
128
+ missing_on_disk = sorted(indexed - on_disk)
129
+
130
+ if missing_from_index:
131
+ print("Files on disk but missing from index.json:")
132
+ for f in missing_from_index:
133
+ print(f" {f}")
134
+ if missing_on_disk:
135
+ print("Entries in index.json with no file on disk:")
136
+ for f in missing_on_disk:
137
+ print(f" {f}")
138
+
139
+ if missing_from_index or missing_on_disk:
140
+ sys.exit(1)
141
+ print(f"index.json consistent with {len(on_disk)} blueprint files.")
142
+ EOF
143
+
144
+ ansible-syntax:
145
+ name: Ansible syntax check
146
+ runs-on: ubuntu-latest
147
+ steps:
148
+ - uses: actions/checkout@v4
149
+ - name: Install Ansible
150
+ run: pip install ansible-core
151
+ - name: Check playbook syntax (if site.yml exists)
152
+ run: |
153
+ if [ -f ansible/site.yml ]; then
154
+ ansible-playbook --syntax-check ansible/site.yml
155
+ else
156
+ echo "No ansible/site.yml — skipping"
157
+ fi
@@ -0,0 +1,32 @@
1
+ name: DCO
2
+
3
+ on:
4
+ pull_request:
5
+
6
+ jobs:
7
+ dco:
8
+ name: DCO
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ with:
13
+ fetch-depth: 0
14
+ - name: Check Signed-off-by on all PR commits
15
+ env:
16
+ BASE_SHA: ${{ github.event.pull_request.base.sha }}
17
+ HEAD_SHA: ${{ github.event.pull_request.head.sha }}
18
+ run: |
19
+ missing=0
20
+ for sha in $(git rev-list --no-merges "$BASE_SHA".."$HEAD_SHA"); do
21
+ if ! git log -1 --format=%B "$sha" | grep -Eqi '^Signed-off-by: .+ <.+@.+>'; then
22
+ echo "::error::Commit $sha is missing a Signed-off-by line (use 'git commit -s')."
23
+ git log -1 --format='%h %s' "$sha"
24
+ missing=1
25
+ fi
26
+ done
27
+ if [ "$missing" -eq 1 ]; then
28
+ echo "All commits must be signed off per the Developer Certificate of Origin:"
29
+ echo "https://developercertificate.org/"
30
+ exit 1
31
+ fi
32
+ echo "All commits signed off."
@@ -0,0 +1,54 @@
1
+ name: Refresh AWS AMI Catalog Defaults
2
+
3
+ on:
4
+ schedule:
5
+ - cron: '0 6 * * 1' # Monday 06:00 UTC
6
+ workflow_dispatch: # allow manual trigger
7
+
8
+ permissions:
9
+ contents: write
10
+ pull-requests: write
11
+
12
+ jobs:
13
+ refresh:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - name: Set up Python
19
+ uses: actions/setup-python@v5
20
+ with:
21
+ python-version: '3.11'
22
+
23
+ - name: Install boto3
24
+ run: pip install boto3
25
+
26
+ - name: Resolve latest AMIs and update catalog
27
+ env:
28
+ AWS_ACCESS_KEY_ID: ${{ secrets.AMI_REFRESH_AWS_ACCESS_KEY_ID }}
29
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AMI_REFRESH_AWS_SECRET_ACCESS_KEY }}
30
+ AWS_DEFAULT_REGION: us-east-1
31
+ run: python scripts/refresh_ami_catalog.py
32
+
33
+ - name: Check for changes
34
+ id: diff
35
+ run: |
36
+ git diff --quiet stratum/core/os_catalog.py || echo "changed=true" >> "$GITHUB_OUTPUT"
37
+
38
+ - name: Commit and open PR
39
+ if: steps.diff.outputs.changed == 'true'
40
+ env:
41
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
42
+ run: |
43
+ git config user.name "github-actions[bot]"
44
+ git config user.email "github-actions[bot]@users.noreply.github.com"
45
+ BRANCH="chore/refresh-amis-$(date +%Y%m%d)"
46
+ git checkout -b "$BRANCH"
47
+ git add stratum/core/os_catalog.py
48
+ git commit -m "chore: refresh AWS AMI catalog defaults $(date +%Y-%m-%d)"
49
+ git push origin "$BRANCH"
50
+ gh pr create \
51
+ --title "chore: refresh AWS AMI catalog defaults $(date +%Y-%m-%d)" \
52
+ --body "Automated weekly AMI refresh. Fallback AMI IDs in \`os_catalog.py\` updated to current us-east-1 values." \
53
+ --base main \
54
+ --head "$BRANCH"
@@ -0,0 +1,102 @@
1
+ name: Release
2
+
3
+ # Publishes to PyPI via trusted publishing (OIDC — no stored API token).
4
+ # Requires a "pending publisher" (first release) or publisher configured on
5
+ # pypi.org for project `stratumoss`: owner StratumOSS, repo Stratum,
6
+ # workflow release.yml, environment pypi.
7
+
8
+ on:
9
+ push:
10
+ tags: ["v*"]
11
+
12
+ jobs:
13
+ build:
14
+ name: Build distributions
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - uses: astral-sh/setup-uv@v5
19
+ with:
20
+ python-version: "3.11"
21
+ - name: Check tag matches package version
22
+ run: |
23
+ pkg_version=$(uv run --no-project python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
24
+ tag_version="${GITHUB_REF_NAME#v}"
25
+ if [ "$pkg_version" != "$tag_version" ]; then
26
+ echo "Tag $GITHUB_REF_NAME does not match pyproject version $pkg_version" >&2
27
+ exit 1
28
+ fi
29
+ - run: uv build
30
+ - name: Smoke-test the wheel
31
+ run: |
32
+ uv venv /tmp/smoke && VIRTUAL_ENV=/tmp/smoke uv pip install dist/*.whl
33
+ cd /tmp && /tmp/smoke/bin/python -c "from stratum.main import app; import stratum; print('import OK', stratum.__version__)"
34
+ - uses: actions/upload-artifact@v4
35
+ with:
36
+ name: dist
37
+ path: dist/
38
+
39
+ publish:
40
+ name: Publish to PyPI
41
+ needs: build
42
+ runs-on: ubuntu-latest
43
+ environment:
44
+ name: pypi
45
+ url: https://pypi.org/project/stratumoss/
46
+ permissions:
47
+ id-token: write
48
+ steps:
49
+ - uses: actions/download-artifact@v4
50
+ with:
51
+ name: dist
52
+ path: dist/
53
+ - uses: pypa/gh-action-pypi-publish@release/v1
54
+
55
+ publish-image:
56
+ name: Publish container image to GHCR
57
+ needs: build
58
+ runs-on: ubuntu-latest
59
+ permissions:
60
+ contents: read
61
+ packages: write
62
+ steps:
63
+ - uses: actions/checkout@v4
64
+ - uses: docker/setup-buildx-action@v3
65
+ - uses: docker/login-action@v3
66
+ with:
67
+ registry: ghcr.io
68
+ username: ${{ github.actor }}
69
+ password: ${{ secrets.GITHUB_TOKEN }}
70
+ - uses: docker/metadata-action@v5
71
+ id: meta
72
+ with:
73
+ images: ghcr.io/stratumoss/stratum
74
+ tags: |
75
+ type=semver,pattern={{version}}
76
+ type=semver,pattern={{major}}.{{minor}}
77
+ - uses: docker/build-push-action@v6
78
+ with:
79
+ context: .
80
+ push: true
81
+ tags: ${{ steps.meta.outputs.tags }}
82
+ labels: ${{ steps.meta.outputs.labels }}
83
+
84
+ github-release:
85
+ name: Create GitHub release
86
+ needs: publish
87
+ runs-on: ubuntu-latest
88
+ permissions:
89
+ contents: write
90
+ steps:
91
+ - uses: actions/checkout@v4
92
+ - uses: actions/download-artifact@v4
93
+ with:
94
+ name: dist
95
+ path: dist/
96
+ - name: Create release with dist artifacts
97
+ env:
98
+ GH_TOKEN: ${{ github.token }}
99
+ run: |
100
+ gh release create "$GITHUB_REF_NAME" dist/* \
101
+ --title "$GITHUB_REF_NAME" \
102
+ --notes "See [CHANGELOG.md](https://github.com/StratumOSS/Stratum/blob/main/CHANGELOG.md) for details."
@@ -0,0 +1,48 @@
1
+ name: Weekly Image Refresh
2
+
3
+ on:
4
+ schedule:
5
+ - cron: "0 3 * * 1" # Monday 03:00 UTC
6
+ workflow_dispatch:
7
+
8
+ jobs:
9
+ refresh:
10
+ name: Trigger official blueprint builds
11
+ runs-on: ubuntu-latest
12
+ env:
13
+ STRATUM_API_URL: ${{ vars.STRATUM_API_URL }}
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: astral-sh/setup-uv@v5
17
+ with:
18
+ python-version: "3.11"
19
+ - run: uv sync
20
+ - name: Run official build trigger
21
+ id: trigger
22
+ run: uv run python scripts/trigger_official_builds.py
23
+ env:
24
+ STRATUM_API_URL: ${{ env.STRATUM_API_URL }}
25
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
26
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
27
+ AWS_DEFAULT_REGION: ${{ vars.AWS_DEFAULT_REGION || 'us-east-1' }}
28
+
29
+ - name: Notify Slack on failure
30
+ if: failure()
31
+ uses: slackapi/slack-github-action@v2
32
+ with:
33
+ payload: |
34
+ {
35
+ "text": ":warning: *Stratum Weekly Image Refresh failed*",
36
+ "blocks": [
37
+ {
38
+ "type": "section",
39
+ "text": {
40
+ "type": "mrkdwn",
41
+ "text": ":warning: *Weekly Image Refresh failed*\nWorkflow: <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Run>"
42
+ }
43
+ }
44
+ ]
45
+ }
46
+ env:
47
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
48
+ SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
@@ -0,0 +1,57 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.pyo
5
+ *.pyd
6
+ .Python
7
+ *.so
8
+ .venv/
9
+ venv/
10
+ env/
11
+ .env
12
+ *.egg-info/
13
+ dist/
14
+ build/
15
+ .pytest_cache/
16
+ .ruff_cache/
17
+ .mypy_cache/
18
+
19
+ # uv
20
+ .uv/
21
+ uv.lock
22
+
23
+ # Stratum runtime data (never commit credentials or build artifacts)
24
+ data/credentials.enc
25
+ data/.stratum_key
26
+ data/.stratum_salt
27
+ data/.admin_token
28
+ data/audits/
29
+ data/builds/
30
+ data/local-images/
31
+ data/scap-content/
32
+ data/audit_jobs.json
33
+ data/api_keys.json
34
+ data/webhooks.json
35
+ profiles/community/
36
+ profiles/user/
37
+
38
+ # Test / coverage artifacts
39
+ .coverage
40
+ coverage.xml
41
+ htmlcov/
42
+
43
+ # OS
44
+ .DS_Store
45
+ Thumbs.db
46
+
47
+ # IDE
48
+ .idea/
49
+ .vscode/
50
+ *.swp
51
+ *.swo
52
+
53
+ # Claude Code / AI assistant local files — never commit
54
+ .claude/
55
+ CLAUDE.md
56
+ CLAUDE.local.md
57
+ .mcp.json
@@ -0,0 +1 @@
1
+ 3.11