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.
- stratumoss-0.5.2/.dockerignore +8 -0
- stratumoss-0.5.2/.env.example +76 -0
- stratumoss-0.5.2/.github/CODEOWNERS +3 -0
- stratumoss-0.5.2/.github/ISSUE_TEMPLATE/bug_report.md +35 -0
- stratumoss-0.5.2/.github/ISSUE_TEMPLATE/feature_request.md +21 -0
- stratumoss-0.5.2/.github/PULL_REQUEST_TEMPLATE.md +27 -0
- stratumoss-0.5.2/.github/dependabot.yml +17 -0
- stratumoss-0.5.2/.github/workflows/ci.yml +157 -0
- stratumoss-0.5.2/.github/workflows/dco.yml +32 -0
- stratumoss-0.5.2/.github/workflows/refresh-amis.yml +54 -0
- stratumoss-0.5.2/.github/workflows/release.yml +102 -0
- stratumoss-0.5.2/.github/workflows/weekly-image-refresh.yml +48 -0
- stratumoss-0.5.2/.gitignore +57 -0
- stratumoss-0.5.2/.python-version +1 -0
- stratumoss-0.5.2/CHANGELOG.md +291 -0
- stratumoss-0.5.2/CODE_OF_CONDUCT.md +61 -0
- stratumoss-0.5.2/CONTRIBUTING.md +466 -0
- stratumoss-0.5.2/Dockerfile +44 -0
- stratumoss-0.5.2/LICENSE +170 -0
- stratumoss-0.5.2/PKG-INFO +722 -0
- stratumoss-0.5.2/README.md +643 -0
- stratumoss-0.5.2/ROADMAP.md +88 -0
- stratumoss-0.5.2/SECURITY.md +48 -0
- stratumoss-0.5.2/ansible/README.md +79 -0
- stratumoss-0.5.2/ansible/site.yml +55 -0
- stratumoss-0.5.2/blueprints/CONTRIBUTING.md +293 -0
- stratumoss-0.5.2/blueprints/README.md +98 -0
- stratumoss-0.5.2/blueprints/alma/9/cis-l1-aws.yaml +84 -0
- stratumoss-0.5.2/blueprints/amazon-linux/2023/cis-l1-aws.yaml +109 -0
- stratumoss-0.5.2/blueprints/debian/12/cis-l1-aws.yaml +84 -0
- stratumoss-0.5.2/blueprints/debian/12/cis-l1-digitalocean.yaml +69 -0
- stratumoss-0.5.2/blueprints/debian/12/cis-l1-gcp.yaml +71 -0
- stratumoss-0.5.2/blueprints/generic/hardening-blueprint.yaml +85 -0
- stratumoss-0.5.2/blueprints/index.json +20 -0
- stratumoss-0.5.2/blueprints/rocky/9/cis-l1-aws.yaml +90 -0
- stratumoss-0.5.2/blueprints/rocky/9/cis-l1-azure.yaml +78 -0
- stratumoss-0.5.2/blueprints/rocky/9/cis-l1-digitalocean.yaml +76 -0
- stratumoss-0.5.2/blueprints/rocky/9/cis-l1-gcp.yaml +81 -0
- stratumoss-0.5.2/blueprints/rocky/9/cis-l1-linode.yaml +73 -0
- stratumoss-0.5.2/blueprints/rocky/9/cis-l1-proxmox.yaml +79 -0
- stratumoss-0.5.2/blueprints/ubuntu/22.04/cis-l1-aws.yaml +120 -0
- stratumoss-0.5.2/blueprints/ubuntu/22.04/cis-l1-azure.yaml +84 -0
- stratumoss-0.5.2/blueprints/ubuntu/22.04/cis-l1-digitalocean.yaml +75 -0
- stratumoss-0.5.2/blueprints/ubuntu/22.04/cis-l1-gcp.yaml +87 -0
- stratumoss-0.5.2/blueprints/ubuntu/22.04/cis-l1-linode.yaml +82 -0
- stratumoss-0.5.2/blueprints/ubuntu/22.04/cis-l1-proxmox.yaml +89 -0
- stratumoss-0.5.2/deploy/aws/README.md +64 -0
- stratumoss-0.5.2/deploy/aws/stratum-builder-role.yaml +128 -0
- stratumoss-0.5.2/deploy/aws/stratum-scanner-role.yaml +117 -0
- stratumoss-0.5.2/deploy/azure/README.md +45 -0
- stratumoss-0.5.2/deploy/azure/stratum-builder-role.json +151 -0
- stratumoss-0.5.2/deploy/azure/stratum-scanner-role.json +139 -0
- stratumoss-0.5.2/deploy/gcp/README.md +51 -0
- stratumoss-0.5.2/deploy/gcp/builder/onboard.sh +85 -0
- stratumoss-0.5.2/deploy/gcp/builder/stratum-builder-role.yaml +35 -0
- stratumoss-0.5.2/deploy/gcp/scanner/onboard.sh +76 -0
- stratumoss-0.5.2/deploy/gcp/scanner/stratum-scanner-role.yaml +29 -0
- stratumoss-0.5.2/docker-compose.yml +58 -0
- stratumoss-0.5.2/docs/api.md +74 -0
- stratumoss-0.5.2/docs/assets/cloud-onboarding.svg +41 -0
- stratumoss-0.5.2/docs/assets/compliance-report.svg +28 -0
- stratumoss-0.5.2/docs/assets/stratum-dashboard.svg +51 -0
- stratumoss-0.5.2/docs/cloud-onboarding.md +84 -0
- stratumoss-0.5.2/docs/pipeline.md +647 -0
- stratumoss-0.5.2/docs/stratum-blueprints-template.yaml +275 -0
- stratumoss-0.5.2/docs/test_plan.md +373 -0
- stratumoss-0.5.2/docs/user-guide.md +44 -0
- stratumoss-0.5.2/docs/ux-flow-cis-l2-amazon-linux-2023.md +672 -0
- stratumoss-0.5.2/input.css +3 -0
- stratumoss-0.5.2/plugins/catalog/azure.py +525 -0
- stratumoss-0.5.2/plugins/catalog/digitalocean.py +523 -0
- stratumoss-0.5.2/plugins/catalog/gcp.py +563 -0
- stratumoss-0.5.2/plugins/catalog/index.json +93 -0
- stratumoss-0.5.2/plugins/catalog/linode.py +463 -0
- stratumoss-0.5.2/plugins/catalog/proxmox.py +487 -0
- stratumoss-0.5.2/plugins/providers/README.md +49 -0
- stratumoss-0.5.2/plugins/providers/_provider_utils.py +905 -0
- stratumoss-0.5.2/plugins/providers/_qemu_utils.py +378 -0
- stratumoss-0.5.2/plugins/providers/aws.py +749 -0
- stratumoss-0.5.2/plugins/providers/azure.py +501 -0
- stratumoss-0.5.2/plugins/providers/digitalocean.py +464 -0
- stratumoss-0.5.2/plugins/providers/example_local.py +220 -0
- stratumoss-0.5.2/plugins/providers/gcp.py +579 -0
- stratumoss-0.5.2/plugins/providers/kvm.py +277 -0
- stratumoss-0.5.2/plugins/providers/linode.py +440 -0
- stratumoss-0.5.2/plugins/providers/proxmox.py +470 -0
- stratumoss-0.5.2/profiles/examples/ubuntu22_cis_l1.yaml +64 -0
- stratumoss-0.5.2/profiles/templates/alma9-cis-l1-aws.yaml +84 -0
- stratumoss-0.5.2/profiles/templates/amazon-linux-2023-cis-l1-aws.yaml +109 -0
- stratumoss-0.5.2/profiles/templates/debian12-cis-l1-aws.yaml +84 -0
- stratumoss-0.5.2/profiles/templates/debian12-cis-l1-digitalocean.yaml +69 -0
- stratumoss-0.5.2/profiles/templates/debian12-cis-l1-gcp.yaml +71 -0
- stratumoss-0.5.2/profiles/templates/generic-hardening-blueprint.yaml +85 -0
- stratumoss-0.5.2/profiles/templates/rocky9-cis-l1-aws.yaml +90 -0
- stratumoss-0.5.2/profiles/templates/rocky9-cis-l1-azure.yaml +78 -0
- stratumoss-0.5.2/profiles/templates/rocky9-cis-l1-digitalocean.yaml +76 -0
- stratumoss-0.5.2/profiles/templates/rocky9-cis-l1-gcp.yaml +81 -0
- stratumoss-0.5.2/profiles/templates/rocky9-cis-l1-linode.yaml +73 -0
- stratumoss-0.5.2/profiles/templates/rocky9-cis-l1-proxmox.yaml +79 -0
- stratumoss-0.5.2/profiles/templates/ubuntu22-cis-l1-aws.yaml +120 -0
- stratumoss-0.5.2/profiles/templates/ubuntu22-cis-l1-azure.yaml +84 -0
- stratumoss-0.5.2/profiles/templates/ubuntu22-cis-l1-digitalocean.yaml +75 -0
- stratumoss-0.5.2/profiles/templates/ubuntu22-cis-l1-gcp.yaml +87 -0
- stratumoss-0.5.2/profiles/templates/ubuntu22-cis-l1-linode.yaml +82 -0
- stratumoss-0.5.2/profiles/templates/ubuntu22-cis-l1-proxmox.yaml +89 -0
- stratumoss-0.5.2/pyproject.toml +119 -0
- stratumoss-0.5.2/scripts/refresh_ami_catalog.py +110 -0
- stratumoss-0.5.2/scripts/trigger_official_builds.py +161 -0
- stratumoss-0.5.2/stratum/__init__.py +5 -0
- stratumoss-0.5.2/stratum/api/__init__.py +2 -0
- stratumoss-0.5.2/stratum/api/agent.py +105 -0
- stratumoss-0.5.2/stratum/api/api_keys.py +37 -0
- stratumoss-0.5.2/stratum/api/auditor.py +353 -0
- stratumoss-0.5.2/stratum/api/blueprints.py +284 -0
- stratumoss-0.5.2/stratum/api/builder.py +815 -0
- stratumoss-0.5.2/stratum/api/integrations.py +594 -0
- stratumoss-0.5.2/stratum/api/pipeline.py +263 -0
- stratumoss-0.5.2/stratum/api/plugins.py +190 -0
- stratumoss-0.5.2/stratum/api/registry.py +37 -0
- stratumoss-0.5.2/stratum/api/ui.py +518 -0
- stratumoss-0.5.2/stratum/api/webhooks.py +76 -0
- stratumoss-0.5.2/stratum/config.py +56 -0
- stratumoss-0.5.2/stratum/core/__init__.py +2 -0
- stratumoss-0.5.2/stratum/core/agent.py +591 -0
- stratumoss-0.5.2/stratum/core/api_keys.py +79 -0
- stratumoss-0.5.2/stratum/core/auditor.py +356 -0
- stratumoss-0.5.2/stratum/core/auth.py +98 -0
- stratumoss-0.5.2/stratum/core/blueprint.py +201 -0
- stratumoss-0.5.2/stratum/core/builder.py +203 -0
- stratumoss-0.5.2/stratum/core/llm/__init__.py +14 -0
- stratumoss-0.5.2/stratum/core/llm/anthropic_backend.py +73 -0
- stratumoss-0.5.2/stratum/core/llm/base.py +56 -0
- stratumoss-0.5.2/stratum/core/llm/bedrock_backend.py +195 -0
- stratumoss-0.5.2/stratum/core/llm/factory.py +124 -0
- stratumoss-0.5.2/stratum/core/llm/openai_backend.py +284 -0
- stratumoss-0.5.2/stratum/core/notifications.py +152 -0
- stratumoss-0.5.2/stratum/core/os_catalog.py +1818 -0
- stratumoss-0.5.2/stratum/core/parser.py +150 -0
- stratumoss-0.5.2/stratum/core/playbook_gen.py +412 -0
- stratumoss-0.5.2/stratum/core/registry.py +238 -0
- stratumoss-0.5.2/stratum/core/report.py +407 -0
- stratumoss-0.5.2/stratum/main.py +127 -0
- stratumoss-0.5.2/stratum/openscap/__init__.py +2 -0
- stratumoss-0.5.2/stratum/openscap/parser.py +115 -0
- stratumoss-0.5.2/stratum/openscap/scanner.py +94 -0
- stratumoss-0.5.2/stratum/paths.py +20 -0
- stratumoss-0.5.2/stratum/plugins/__init__.py +2 -0
- stratumoss-0.5.2/stratum/plugins/base_provider.py +52 -0
- stratumoss-0.5.2/stratum/plugins/loader.py +145 -0
- stratumoss-0.5.2/stratum/plugins/registry.py +57 -0
- stratumoss-0.5.2/stratum/plugins/subprocess_provider.py +184 -0
- stratumoss-0.5.2/stratum/static/css/tailwind.css +2075 -0
- stratumoss-0.5.2/stratum/static/js/htmx.min.js +1 -0
- stratumoss-0.5.2/stratum/templates/agent/index.html +366 -0
- stratumoss-0.5.2/stratum/templates/auditor/compare.html +110 -0
- stratumoss-0.5.2/stratum/templates/auditor/history.html +104 -0
- stratumoss-0.5.2/stratum/templates/auditor/index.html +60 -0
- stratumoss-0.5.2/stratum/templates/auditor/report.html +298 -0
- stratumoss-0.5.2/stratum/templates/auditor/results.html +100 -0
- stratumoss-0.5.2/stratum/templates/auditor/scan_image.html +110 -0
- stratumoss-0.5.2/stratum/templates/auditor/scan_image_results.html +196 -0
- stratumoss-0.5.2/stratum/templates/auditor/scanner/steps/step1_target.html +209 -0
- stratumoss-0.5.2/stratum/templates/auditor/scanner/steps/step2_benchmark.html +172 -0
- stratumoss-0.5.2/stratum/templates/auditor/scanner/steps/step3_review.html +136 -0
- stratumoss-0.5.2/stratum/templates/auditor/scanner/wizard.html +114 -0
- stratumoss-0.5.2/stratum/templates/base.html +156 -0
- stratumoss-0.5.2/stratum/templates/blueprints/index.html +314 -0
- stratumoss-0.5.2/stratum/templates/blueprints/studio.html +245 -0
- stratumoss-0.5.2/stratum/templates/builder/index.html +64 -0
- stratumoss-0.5.2/stratum/templates/builder/run.html +27 -0
- stratumoss-0.5.2/stratum/templates/builder/steps/step1_os.html +178 -0
- stratumoss-0.5.2/stratum/templates/builder/steps/step2_storage.html +512 -0
- stratumoss-0.5.2/stratum/templates/builder/steps/step3_users.html +224 -0
- stratumoss-0.5.2/stratum/templates/builder/steps/step4_hardening.html +237 -0
- stratumoss-0.5.2/stratum/templates/builder/steps/step5_review.html +335 -0
- stratumoss-0.5.2/stratum/templates/builder/wizard.html +145 -0
- stratumoss-0.5.2/stratum/templates/index.html +183 -0
- stratumoss-0.5.2/stratum/templates/integrations/index.html +85 -0
- stratumoss-0.5.2/stratum/templates/integrations/partials/available_plugins.html +34 -0
- stratumoss-0.5.2/stratum/templates/integrations/partials/aws.html +244 -0
- stratumoss-0.5.2/stratum/templates/integrations/partials/azure.html +118 -0
- stratumoss-0.5.2/stratum/templates/integrations/partials/gcp.html +106 -0
- stratumoss-0.5.2/stratum/templates/integrations/partials/generic.html +111 -0
- stratumoss-0.5.2/stratum/templates/integrations/partials/install_success.html +7 -0
- stratumoss-0.5.2/stratum/templates/integrations/partials/remove_success.html +7 -0
- stratumoss-0.5.2/stratum/templates/partials/blueprint_yaml.html +10 -0
- stratumoss-0.5.2/stratum/templates/partials/job_status.html +143 -0
- stratumoss-0.5.2/stratum/templates/partials/provider_fields.html +36 -0
- stratumoss-0.5.2/stratum/templates/partials/report_table.html +59 -0
- stratumoss-0.5.2/stratum/templates/settings/api_keys.html +159 -0
- stratumoss-0.5.2/stratum/templates/settings/webhooks.html +216 -0
- stratumoss-0.5.2/tailwind.config.js +19 -0
- stratumoss-0.5.2/tests/__init__.py +2 -0
- stratumoss-0.5.2/tests/api/__init__.py +1 -0
- stratumoss-0.5.2/tests/api/conftest.py +169 -0
- stratumoss-0.5.2/tests/api/test_api_agent_sse.py +152 -0
- stratumoss-0.5.2/tests/api/test_api_api_keys.py +109 -0
- stratumoss-0.5.2/tests/api/test_api_auditor.py +301 -0
- stratumoss-0.5.2/tests/api/test_api_blueprints.py +313 -0
- stratumoss-0.5.2/tests/api/test_api_blueprints_extended.py +274 -0
- stratumoss-0.5.2/tests/api/test_api_builder.py +557 -0
- stratumoss-0.5.2/tests/api/test_api_coverage_gaps.py +383 -0
- stratumoss-0.5.2/tests/api/test_api_integrations.py +956 -0
- stratumoss-0.5.2/tests/api/test_api_pipeline.py +537 -0
- stratumoss-0.5.2/tests/api/test_api_plugins.py +142 -0
- stratumoss-0.5.2/tests/api/test_api_plugins_auditor_pipeline.py +291 -0
- stratumoss-0.5.2/tests/api/test_api_registry.py +114 -0
- stratumoss-0.5.2/tests/api/test_api_ui.py +261 -0
- stratumoss-0.5.2/tests/api/test_api_webhooks.py +225 -0
- stratumoss-0.5.2/tests/api/test_edge_cases.py +373 -0
- stratumoss-0.5.2/tests/conftest.py +18 -0
- stratumoss-0.5.2/tests/integration/__init__.py +2 -0
- stratumoss-0.5.2/tests/integration/conftest.py +139 -0
- stratumoss-0.5.2/tests/integration/test_aws_e2e.py +473 -0
- stratumoss-0.5.2/tests/providers/__init__.py +0 -0
- stratumoss-0.5.2/tests/providers/test_provider_aws.py +307 -0
- stratumoss-0.5.2/tests/providers/test_provider_azure.py +214 -0
- stratumoss-0.5.2/tests/providers/test_provider_contract.py +245 -0
- stratumoss-0.5.2/tests/providers/test_provider_digitalocean.py +202 -0
- stratumoss-0.5.2/tests/providers/test_provider_gcp.py +255 -0
- stratumoss-0.5.2/tests/providers/test_provider_kvm.py +242 -0
- stratumoss-0.5.2/tests/providers/test_provider_linode.py +220 -0
- stratumoss-0.5.2/tests/providers/test_provider_proxmox.py +283 -0
- stratumoss-0.5.2/tests/providers/test_provider_utils.py +572 -0
- stratumoss-0.5.2/tests/providers/test_qemu_utils.py +346 -0
- stratumoss-0.5.2/tests/security/__init__.py +0 -0
- stratumoss-0.5.2/tests/security/test_api_key_security.py +75 -0
- stratumoss-0.5.2/tests/security/test_blueprint_security.py +125 -0
- stratumoss-0.5.2/tests/security/test_webhook_security.py +145 -0
- stratumoss-0.5.2/tests/test_agent_core.py +773 -0
- stratumoss-0.5.2/tests/test_api_keys.py +154 -0
- stratumoss-0.5.2/tests/test_auditor_core.py +541 -0
- stratumoss-0.5.2/tests/test_blueprint.py +88 -0
- stratumoss-0.5.2/tests/test_cloud_onboarding_templates.py +89 -0
- stratumoss-0.5.2/tests/test_core_builder.py +280 -0
- stratumoss-0.5.2/tests/test_credential_store.py +211 -0
- stratumoss-0.5.2/tests/test_final_gaps.py +272 -0
- stratumoss-0.5.2/tests/test_gaps.py +398 -0
- stratumoss-0.5.2/tests/test_llm_backends.py +283 -0
- stratumoss-0.5.2/tests/test_llm_backends_extended.py +726 -0
- stratumoss-0.5.2/tests/test_notifications.py +261 -0
- stratumoss-0.5.2/tests/test_openai_backend_toolcalls.py +368 -0
- stratumoss-0.5.2/tests/test_openscap_parser.py +158 -0
- stratumoss-0.5.2/tests/test_packaging_paths.py +213 -0
- stratumoss-0.5.2/tests/test_persistence.py +177 -0
- stratumoss-0.5.2/tests/test_pipeline_logic.py +218 -0
- stratumoss-0.5.2/tests/test_playbook_gen.py +370 -0
- stratumoss-0.5.2/tests/test_plugin_loader.py +226 -0
- stratumoss-0.5.2/tests/test_plugins_extended.py +299 -0
- stratumoss-0.5.2/tests/test_registry.py +333 -0
- stratumoss-0.5.2/tests/test_regression.py +136 -0
- stratumoss-0.5.2/tests/test_remaining_gaps.py +466 -0
- stratumoss-0.5.2/tests/test_report.py +514 -0
- stratumoss-0.5.2/tests/test_sarif.py +215 -0
- stratumoss-0.5.2/tests/test_scanner.py +139 -0
- stratumoss-0.5.2/tests/test_scap_parser.py +168 -0
- stratumoss-0.5.2/tests/test_subprocess_provider.py +296 -0
- stratumoss-0.5.2/tests/ui/__init__.py +0 -0
- stratumoss-0.5.2/tests/ui/test_pages.py +369 -0
- stratumoss-0.5.2/update_templates.py +39 -0
|
@@ -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,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
|