release: prepare v0.9.7

This commit is contained in:
BigBodyCobain
2026-05-01 22:55:04 -06:00
parent ea457f27da
commit 28b3bd5ebf
670 changed files with 187060 additions and 14006 deletions
+167 -2
View File
@@ -1,7 +1,9 @@
import argparse
import hashlib
import json
import os
import sys
from datetime import datetime, timezone
from pathlib import Path
@@ -56,6 +58,72 @@ def sha256_file(path: Path) -> str:
return digest.hexdigest().lower()
def _default_generated_at() -> str:
return datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
def build_release_attestation(
*,
suite_green: bool,
suite_name: str = "dm_relay_security",
detail: str = "",
report: str = "",
command: str = "",
commit: str = "",
generated_at: str = "",
threat_model_reference: str = "docs/mesh/threat-model.md",
workflow: str = "",
run_id: str = "",
run_attempt: str = "",
ref: str = "",
) -> dict:
normalized_generated_at = str(generated_at or "").strip() or _default_generated_at()
normalized_commit = str(commit or "").strip() or os.environ.get("GITHUB_SHA", "").strip()
normalized_workflow = str(workflow or "").strip() or os.environ.get("GITHUB_WORKFLOW", "").strip()
normalized_run_id = str(run_id or "").strip() or os.environ.get("GITHUB_RUN_ID", "").strip()
normalized_run_attempt = str(run_attempt or "").strip() or os.environ.get("GITHUB_RUN_ATTEMPT", "").strip()
normalized_ref = str(ref or "").strip() or os.environ.get("GITHUB_REF", "").strip()
normalized_suite_name = str(suite_name or "").strip() or "dm_relay_security"
normalized_report = str(report or "").strip()
normalized_command = str(command or "").strip()
normalized_detail = str(detail or "").strip() or (
"CI attestation confirms the DM relay security suite is green."
if suite_green
else "CI attestation recorded a failing DM relay security suite run."
)
payload = {
"generated_at": normalized_generated_at,
"commit": normalized_commit,
"threat_model_reference": str(threat_model_reference or "").strip()
or "docs/mesh/threat-model.md",
"dm_relay_security_suite": {
"name": normalized_suite_name,
"green": bool(suite_green),
"detail": normalized_detail,
"report": normalized_report,
},
}
if normalized_command:
payload["dm_relay_security_suite"]["command"] = normalized_command
ci = {
"workflow": normalized_workflow,
"run_id": normalized_run_id,
"run_attempt": normalized_run_attempt,
"ref": normalized_ref,
}
if any(ci.values()):
payload["ci"] = ci
return payload
def write_release_attestation(output_path: Path | str, **kwargs) -> dict:
path = Path(output_path).resolve()
payload = build_release_attestation(**kwargs)
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(payload, indent=2) + "\n", encoding="utf-8")
return payload
def cmd_show(_args: argparse.Namespace) -> int:
version = current_version()
if not version:
@@ -102,6 +170,30 @@ def cmd_hash(args: argparse.Namespace) -> int:
return 0 if asset_matches else 2
def cmd_write_attestation(args: argparse.Namespace) -> int:
suite_green = bool(args.suite_green)
payload = write_release_attestation(
args.output_path,
suite_green=suite_green,
suite_name=args.suite_name,
detail=args.detail,
report=args.report,
command=args.command,
commit=args.commit,
generated_at=args.generated_at,
threat_model_reference=args.threat_model_reference,
workflow=args.workflow,
run_id=args.run_id,
run_attempt=args.run_attempt,
ref=args.ref,
)
output_path = Path(args.output_path).resolve()
print(f"Wrote release attestation: {output_path}")
print(f"DM relay security suite : {'green' if suite_green else 'red'}")
print(f"Commit : {payload.get('commit', '')}")
return 0
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
description="Helper for ShadowBroker release version/tag/asset consistency."
@@ -112,7 +204,7 @@ def build_parser() -> argparse.ArgumentParser:
show_parser.set_defaults(func=cmd_show)
set_version_parser = subparsers.add_parser("set-version", help="Update frontend/package.json version")
set_version_parser.add_argument("version", help="Version like 0.9.6")
set_version_parser.add_argument("version", help="Version like 0.9.7")
set_version_parser.set_defaults(func=cmd_set_version)
hash_parser = subparsers.add_parser(
@@ -121,10 +213,83 @@ def build_parser() -> argparse.ArgumentParser:
hash_parser.add_argument("zip_path", help="Path to the release ZIP")
hash_parser.add_argument(
"--version",
help="Release version like 0.9.6. Defaults to frontend/package.json version.",
help="Release version like 0.9.7. Defaults to frontend/package.json version.",
)
hash_parser.set_defaults(func=cmd_hash)
attestation_parser = subparsers.add_parser(
"write-attestation",
help="Write a structured Sprint 8 release attestation JSON file",
)
attestation_parser.add_argument("output_path", help="Where to write the attestation JSON")
suite_group = attestation_parser.add_mutually_exclusive_group(required=True)
suite_group.add_argument(
"--suite-green",
action="store_true",
help="Mark the DM relay security suite as green",
)
suite_group.add_argument(
"--suite-red",
action="store_true",
help="Mark the DM relay security suite as failing",
)
attestation_parser.add_argument(
"--suite-name",
default="dm_relay_security",
help="Suite name to record in the attestation",
)
attestation_parser.add_argument(
"--detail",
default="",
help="Human-readable suite detail. Defaults to a CI-generated message.",
)
attestation_parser.add_argument(
"--report",
default="",
help="Path to the suite report or artifact reference to embed in the attestation.",
)
attestation_parser.add_argument(
"--command",
default="",
help="Exact suite command used to generate the attestation.",
)
attestation_parser.add_argument(
"--commit",
default="",
help="Commit SHA. Defaults to GITHUB_SHA when available.",
)
attestation_parser.add_argument(
"--generated-at",
default="",
help="UTC timestamp for the attestation. Defaults to current UTC time.",
)
attestation_parser.add_argument(
"--threat-model-reference",
default="docs/mesh/threat-model.md",
help="Threat model reference to embed in the attestation.",
)
attestation_parser.add_argument(
"--workflow",
default="",
help="Workflow name. Defaults to GITHUB_WORKFLOW when available.",
)
attestation_parser.add_argument(
"--run-id",
default="",
help="Workflow run ID. Defaults to GITHUB_RUN_ID when available.",
)
attestation_parser.add_argument(
"--run-attempt",
default="",
help="Workflow run attempt. Defaults to GITHUB_RUN_ATTEMPT when available.",
)
attestation_parser.add_argument(
"--ref",
default="",
help="Git ref. Defaults to GITHUB_REF when available.",
)
attestation_parser.set_defaults(func=cmd_write_attestation)
return parser
@@ -0,0 +1,75 @@
"""Rotate the MESH_SECURE_STORAGE_SECRET used to protect key envelopes at rest.
Usage — stop the backend first, then run:
MESH_OLD_STORAGE_SECRET=<current> \\
MESH_NEW_STORAGE_SECRET=<new> \\
python -m scripts.rotate_secure_storage_secret
Dry-run mode (validates old secret without writing anything):
MESH_OLD_STORAGE_SECRET=<current> \\
MESH_NEW_STORAGE_SECRET=<new> \\
python -m scripts.rotate_secure_storage_secret --dry-run
Or, for Docker deployments:
docker exec -e MESH_OLD_STORAGE_SECRET=<current> \\
-e MESH_NEW_STORAGE_SECRET=<new> \\
<container> python -m scripts.rotate_secure_storage_secret
After successful rotation, update your .env (or Docker secret file) to set
MESH_SECURE_STORAGE_SECRET to the new value, then restart the backend.
The script fails closed: if the old secret cannot unwrap any existing envelope,
nothing is written. Non-passphrase envelopes (DPAPI, raw) are skipped with a
warning.
Before rewriting, .bak copies of every envelope are created so a mid-rotation
crash leaves recoverable backups on disk.
"""
from __future__ import annotations
import json
import os
import sys
def main() -> None:
dry_run = "--dry-run" in sys.argv
old_secret = os.environ.get("MESH_OLD_STORAGE_SECRET", "").strip()
new_secret = os.environ.get("MESH_NEW_STORAGE_SECRET", "").strip()
if not old_secret:
print("ERROR: MESH_OLD_STORAGE_SECRET environment variable is required.", file=sys.stderr)
sys.exit(1)
if not new_secret:
print("ERROR: MESH_NEW_STORAGE_SECRET environment variable is required.", file=sys.stderr)
sys.exit(1)
from services.mesh.mesh_secure_storage import SecureStorageError, rotate_storage_secret
try:
result = rotate_storage_secret(old_secret, new_secret, dry_run=dry_run)
except SecureStorageError as exc:
print(f"ROTATION FAILED: {exc}", file=sys.stderr)
sys.exit(1)
print(json.dumps(result, indent=2))
if dry_run:
print(
"\nDry run complete. No files were modified. Run again without --dry-run to perform the rotation.",
file=sys.stderr,
)
else:
print(
"\nRotation complete. Update MESH_SECURE_STORAGE_SECRET to the new value and restart the backend."
"\nBackup files (.bak) were created alongside each rotated envelope.",
file=sys.stderr,
)
if __name__ == "__main__":
main()
+9 -3
View File
@@ -1,10 +1,16 @@
param(
[string]$Python = "python"
[string]$Python = "py"
)
$repoRoot = Resolve-Path (Join-Path $PSScriptRoot "..")
$venvPath = Join-Path $repoRoot "venv"
& $Python -m venv $venvPath
$venvMarker = Join-Path $repoRoot ".venv-dir"
& $Python -3.11 -m venv $venvPath
$pip = Join-Path $venvPath "Scripts\pip.exe"
& $pip install -r (Join-Path $repoRoot "requirements-dev.txt")
& $pip install --upgrade pip
Push-Location $repoRoot
& (Join-Path $venvPath "Scripts\python.exe") -m pip install -e .
& $pip install pytest pytest-asyncio ruff black
"venv" | Set-Content -LiteralPath $venvMarker -NoNewline
Pop-Location
+7 -2
View File
@@ -1,9 +1,14 @@
#!/usr/bin/env bash
set -euo pipefail
PYTHON="${PYTHON:-python3}"
PYTHON="${PYTHON:-python3.11}"
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
VENV_DIR="$REPO_ROOT/venv"
VENV_MARKER="$REPO_ROOT/.venv-dir"
"$PYTHON" -m venv "$VENV_DIR"
"$VENV_DIR/bin/pip" install -r "$REPO_ROOT/requirements-dev.txt"
"$VENV_DIR/bin/pip" install --upgrade pip
cd "$REPO_ROOT"
"$VENV_DIR/bin/python" -m pip install -e .
"$VENV_DIR/bin/pip" install pytest pytest-asyncio ruff black
printf 'venv\n' > "$VENV_MARKER"