Publish curated Unraid-AppOps-Gateway source from 4f99d8f6ea4fb8ae105b83570344b25fa05c31fd

This commit is contained in:
Public Source Publisher committed 2026-10-02 18:50:59 +00:00
1 parent 27a33107a3
commit f50d6e8c2c
14 files changed
+1178 -21

No files matched your search

@@ -29,6 +29,7 @@ def test_controller_promoter_helper_spec_is_fixed_and_bounded():
spec = helper_container_spec(revision=revision, image_id=image_id)
assert HELPER_NAME == "itworx-controller-artifact-promoter"
assert CONTROLLER_VERSION == "2.1.13"
assert re.fullmatch(r"2\.1\.\d+", CONTROLLER_VERSION)
assert spec["Image"] == image_id
assert spec["HostConfig"]["Privileged"] is False
@@ -53,6 +54,9 @@ def test_controller_promoter_helper_spec_is_fixed_and_bounded():
assert "rm -rf -- \"$work\"" in command
assert "chmod 0600 \"$work/controller.tar\"" in command
assert "scripts/prepare_controller_hub_release_volume.py" in command
archive_start = command.index('git --git-dir="$repo" archive')
archive_end = command.index('> "$work/controller.tar"', archive_start)
assert "scripts/vendor" in command[archive_start:archive_end]
assert "scripts/upgrade_deployment_controller.sh > \"$work/controller.tar\"" in command
assert f"--image-id '{image_id}'" in command
@@ -264,6 +264,107 @@ def test_previous_private_tls_is_validated_from_the_attested_config_snapshot(
assert calls == []
def test_staged_config_checks_run_new_artifact_with_copied_config_and_bounded_output(
tmp_path, monkeypatch
):
stage_root = tmp_path / "source"
stage_root.mkdir(mode=0o700)
release_tree = (
{
"status_server.py": (b"new status server", 0o644),
"controller-release.json": (b"new release identity", 0o644),
},
{"": 0o755},
)
config_tree = (
{
"projects.json": (b"{\"repo\":{}}", 0o600),
"broker-token": (b"private broker token", 0o600),
"gitea-validation.json": (b"{}", 0o600),
"gitea-validation-token": (b"private validation token", 0o600),
"private-tls.json": (b"private TLS config", 0o600),
"webhook-secrets/repo": (b"private webhook secret", 0o600),
},
{"": 0o755, "webhook-secrets": 0o700},
)
calls = []
validation_root = stage_root / "validation"
def run(arguments, *, data=None, max_output=module.MAX_BYTES):
calls.append((arguments, max_output))
assert (validation_root / "status_server.py").read_bytes() == b"new status server"
assert (validation_root / "projects.json").read_bytes() == b"{\"repo\":{}}"
assert (validation_root / "broker-token").read_bytes() == b"private broker token"
assert (validation_root / "webhook-secrets" / "repo").read_bytes() == b"private webhook secret"
return b"validated"
monkeypatch.setattr(module, "_write_private_tree", _write_test_tree)
monkeypatch.setattr(module, "_run", run)
validator = getattr(module, "_validate_staged_configuration", None)
assert callable(validator), "staged configuration validation helper is required"
validator(stage_root, release_tree, config_tree)
assert calls == [
(["python3", str(validation_root / "status_server.py"), "--check-artifact"], 4096),
(["python3", str(validation_root / "status_server.py"), "--check-config"], 4096),
(["python3", str(validation_root / "status_server.py"), "--check-validation-config"], 4096),
(["python3", str(validation_root / "status_server.py"), "--check-validation-api"], 4096),
(["python3", str(validation_root / "status_server.py"), "--check-private-tls-config"], 4096),
]
assert not validation_root.exists()
def test_staged_config_check_failure_is_sanitized_and_cleans_private_validation_tree(
tmp_path, monkeypatch
):
stage_root = tmp_path / "source"
stage_root.mkdir(mode=0o700)
release_tree = (
{
"status_server.py": (b"new status server", 0o644),
"controller-release.json": (b"new release identity", 0o644),
},
{"": 0o755},
)
config_tree = (
{
"projects.json": (b"{}", 0o600),
"broker-token": (b"top-secret-broker", 0o600),
"gitea-validation.json": (b"{}", 0o600),
"gitea-validation-token": (b"top-secret-validation", 0o600),
},
{"": 0o755},
)
class FailedProcess:
returncode = 1
stdout = b"token=top-secret-validation"
stderr = b"secret=top-secret-broker"
monkeypatch.setattr(module, "_write_private_tree", _write_test_tree)
monkeypatch.setattr(module.subprocess, "run", lambda *args, **kwargs: FailedProcess())
validator = getattr(module, "_validate_staged_configuration", None)
assert callable(validator), "staged configuration validation helper is required"
with pytest.raises(module.VolumeTransitionError, match="command_failed") as error:
validator(stage_root, release_tree, config_tree)
assert "top-secret" not in str(error.value)
assert not (stage_root / "validation").exists()
def _write_test_tree(path, entries, directories):
path.mkdir(mode=0o700)
for relative, _mode in sorted(directories.items(), key=lambda item: item[0].count("/")):
if relative:
(path / relative).mkdir(parents=True, exist_ok=True)
for relative, (contents, _mode) in entries.items():
destination = path / relative
destination.parent.mkdir(parents=True, exist_ok=True)
destination.write_bytes(contents)
@pytest.mark.skipif(os.name == "nt", reason="private TLS snapshot guard requires POSIX symlink semantics")
def test_previous_private_tls_rejects_symlinked_snapshot(tmp_path):
previous = tmp_path / "previous-controller"
@@ -298,12 +399,67 @@ def test_promoted_compose_actions_use_only_stdin_and_fixed_service(compose):
module.compose_action(rendered, "stop")
module.compose_action(rendered, "up")
assert calls[-2][0][-2:] == ["stop", module.SERVICE]
assert calls[-1][0][-5:] == ["up", "-d", "--force-recreate", "--pull", "never", module.SERVICE][-5:]
up_index = calls[-1][0].index("up")
assert calls[-1][0][up_index:] == [
"up", "-d", "--force-recreate", "--pull", "never", "--no-deps", module.SERVICE
]
assert calls[-2][1] == rendered
assert calls[-1][1] == rendered
assert baseline["name"] == "gitea-deploy-runners"
def test_rollback_uses_no_dependencies_when_recreating_prior_controller(compose, tmp_path, monkeypatch):
_baseline, calls = compose
previous = REVISION
target = "c" * 40
previous_compose = module.rendered_model(ORIGINAL_COMPOSE, previous, IMAGE_ID)
target_compose = module.rendered_model(ORIGINAL_COMPOSE, target, IMAGE_ID)
receipt = {
"phase": "activated",
"imageId": IMAGE_ID,
"previousRevision": previous,
"sourceRevision": target,
}
values = {
"controller-before.tar": module._release_tar_bytes(
previous,
({"controller-release.json": (b"previous release", 0o644)}, {"": 0o755}),
),
"controller-after.tar": b"unused by isolated rollback test",
"mirror-before.tar": b"unused by isolated rollback test",
"compose-rollback.json": previous_compose,
"compose-after.json": target_compose,
}
current = {
"Mounts": [{
"Destination": module.EXECUTABLE_TARGET,
"Source": module._expected_revision_path(previous).as_posix(),
}]
}
monkeypatch.setattr(module, "_load_transaction", lambda _backup: (1, receipt, values))
monkeypatch.setattr(module.os, "close", lambda _descriptor: None)
monkeypatch.setattr(module, "_controller_image_inspect", lambda *args, **kwargs: current)
monkeypatch.setattr(module, "_verify_release_leaf", lambda *args, **kwargs: True)
monkeypatch.setattr(module, "_stop_current_controller", lambda *args, **kwargs: None)
monkeypatch.setattr(module, "_sync_controller_mirror", lambda *args, **kwargs: None)
monkeypatch.setattr(module, "_ensure_root_compose", lambda *args, **kwargs: None)
monkeypatch.setattr(module, "_verify_compose_image", lambda *args, **kwargs: None)
monkeypatch.setattr(module, "_verify_active_mount", lambda *args, **kwargs: None)
monkeypatch.setattr(module, "_set_promotion_phase", lambda *args, **kwargs: None)
module.rollback_promotion(tmp_path / "backup")
up_calls = [
arguments for arguments, _data in calls
if arguments[:2] == ["docker", "compose"] and "up" in arguments
]
assert len(up_calls) == 1
up_index = up_calls[0].index("up")
assert up_calls[0][up_index:] == [
"up", "-d", "--force-recreate", "--pull", "never", "--no-deps", module.SERVICE
]
def test_installer_has_no_shared_executable_stage_or_compose_path():
source = (ROOT / "scripts/upgrade_deployment_controller.sh").read_text(encoding="utf-8")
assert "mktemp -d -p /tmp \"itworx-controller-upgrade-" in source
@@ -476,6 +632,11 @@ def test_source_compose_preflight_rejects_unresolvable_alias_keys():
module._preflight_source_compose(source)
def test_source_compose_preflight_bounds_recursive_list_aliases():
source = b"services: {app: {image: fixed}}\nx-loop: &a [*a]\n"
module._preflight_source_compose(source)
@pytest.mark.parametrize(
"source",
[
@@ -53,3 +53,14 @@ def test_windows_wrapper_supplies_private_archive_and_exact_image_identity():
assert "--image-id '$imageId'" in wrapper
assert "--image-id) image_id=\"$2\"" in installer
assert '[[ "$archive_parent" =~ ^/tmp/itworx-controller-artifact-promoter-' in installer
def test_state_reconciliation_is_committed_only_after_volume_verification():
installer = (ROOT / "scripts/upgrade_deployment_controller.sh").read_text(encoding="utf-8")
verify = installer.index('python3 "${work}/${PREPARER_NAME}" verify --backup "$backup"')
commit = installer.index(
'python3 "${work}/reconcile_controller_state.py" --journal-path "$migration_journal" --commit'
)
assert verify < commit
assert installer.index("reconciliation_active=0", commit) > commit
@@ -0,0 +1,277 @@
from __future__ import annotations
import hashlib
import http.client
import importlib.util
import json
import subprocess
import sys
import threading
import types
from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[2]
STATUS_SERVER = ROOT / "ops" / "gitea-deploy-broker" / "status_server.py"
@pytest.fixture
def status_module():
if "fcntl" not in sys.modules:
fcntl = types.ModuleType("fcntl")
fcntl.LOCK_EX = 2
fcntl.LOCK_UN = 8
fcntl.flock = lambda *_args: None
sys.modules["fcntl"] = fcntl
spec = importlib.util.spec_from_file_location("forge_bootstrap_status_test", STATUS_SERVER)
assert spec and spec.loader
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def _request(module, server, body: bytes, *, nonce: str, secret: bytes, signature: str | None = None):
path = module.FORGE_BOOTSTRAP_PREFLIGHT_PATH
timestamp = str(int(module.time.time()))
signature = signature or module._request_signature(
secret,
method="POST",
path=path,
timestamp=timestamp,
nonce=nonce,
raw_body=body,
)
connection = http.client.HTTPConnection(*server.server_address, timeout=2)
connection.request(
"POST",
path,
body=body,
headers={
"Content-Type": "application/json",
"Content-Length": str(len(body)),
"X-ITWorx-Deployment-Timestamp": timestamp,
"X-ITWorx-Deployment-Nonce": nonce,
"X-ITWorx-Deployment-Signature": signature,
},
)
response = connection.getresponse()
status, payload = response.status, json.loads(response.read())
connection.close()
return status, payload
def test_forge_preflight_http_is_signed_strict_replay_safe_and_read_only(
status_module, tmp_path, monkeypatch
):
secret = b"forge-bootstrap-test-secret-" + b"x" * 40
secret_path = tmp_path / "bootstrap"
secret_path.write_bytes(secret)
secret_path.chmod(0o600)
nonce_root = tmp_path / "nonces"
monkeypatch.setattr(status_module, "APPOPS_ENROLLMENT_BOOTSTRAP_SECRET_FILE", secret_path)
monkeypatch.setattr(status_module, "APPOPS_NONCE_ROOT", nonce_root)
calls = []
response = {
"apiVersion": status_module.FORGE_BOOTSTRAP_PREFLIGHT_VERSION,
"status": "preflight_unknown",
"revision": "a" * 40,
"workspaceImageDigest": "sha256:" + "b" * 64,
"frontdoorImageDigest": "sha256:" + "c" * 64,
"checks": {"exact_main": {"status": "unknown"}},
"evidence": {},
}
monkeypatch.setattr(
status_module,
"_forge_bootstrap_runtime_checks",
lambda profile: calls.append(profile) or response,
)
server = status_module.BoundedThreadingHTTPServer(
("127.0.0.1", 0), status_module.Handler
)
serving = threading.Thread(target=server.serve_forever, daemon=True)
serving.start()
profile = {
"api_version": status_module.FORGE_BOOTSTRAP_PREFLIGHT_VERSION,
"revision": "a" * 40,
"workspace_image_digest": "sha256:" + "b" * 64,
"frontdoor_image_digest": "sha256:" + "c" * 64,
}
body = json.dumps({"profile": profile}, sort_keys=True, separators=(",", ":")).encode()
try:
status, payload = _request(
status_module, server, body, nonce="a" * 32, secret=secret
)
assert status == 200
assert payload == response
assert calls == [profile]
assert secret.decode() not in json.dumps(payload)
assert len(list(nonce_root.iterdir())) == 1
replay_status, replay_payload = _request(
status_module, server, body, nonce="a" * 32, secret=secret
)
assert replay_status == 403
assert replay_payload == {"status": "authentication_rejected"}
assert calls == [profile]
hostile = dict(profile, host_path="/etc", endpoint="https://attacker.invalid")
hostile_body = json.dumps(
{"profile": hostile}, sort_keys=True, separators=(",", ":")
).encode()
hostile_status, hostile_payload = _request(
status_module, server, hostile_body, nonce="b" * 32, secret=secret
)
assert hostile_status == 400
assert hostile_payload == {"status": "invalid_forge_preflight_contract"}
assert calls == [profile]
assert len(list(nonce_root.iterdir())) == 1
bad_signature_status, _ = _request(
status_module,
server,
body,
nonce="c" * 32,
secret=secret,
signature="0" * 64,
)
assert bad_signature_status == 403
assert calls == [profile]
finally:
server.shutdown()
server.server_close()
serving.join(timeout=2)
def test_forge_host_preflight_compares_exact_main_and_reports_fixed_runtime_checks(
status_module, tmp_path, monkeypatch
):
revision = "a" * 40
manifest = b"fixed Forge compose candidate"
managed_root = tmp_path / "managed-root"
postgres_dir = managed_root / "itworx-forge" / "postgres"
postgres_dir.mkdir(parents=True)
(managed_root / "itworx-forge").chmod(0o700)
postgres_dir.chmod(0o700)
app_dir = managed_root / "itworx-forge"
monkeypatch.setattr(status_module, "MANAGED_APPDATA_ROOT", managed_root)
monkeypatch.setattr(status_module, "_refresh_appdata_root_selection", lambda: managed_root)
monkeypatch.setattr(status_module, "appdata_root_is_safe", lambda _root: True)
monkeypatch.setattr(
status_module, "os", types.SimpleNamespace(name="posix", geteuid=lambda: 0)
)
original_lstat = Path.lstat
def lstat_with_fixed_service_owners(path):
info = original_lstat(path)
if path == app_dir:
return types.SimpleNamespace(
st_mode=status_module.stat.S_IFDIR | 0o700, st_uid=0, st_gid=0
)
if path == postgres_dir:
return types.SimpleNamespace(
st_mode=status_module.stat.S_IFDIR | 0o700, st_uid=70, st_gid=70
)
return info
monkeypatch.setattr(Path, "lstat", lstat_with_fixed_service_owners)
monkeypatch.setattr(status_module, "_forge_gitea_main_revision", lambda: revision)
monkeypatch.setattr(status_module, "_forge_push_validation", lambda _revision: "unknown")
monkeypatch.setattr(
status_module, "FORGE_COMPOSE_SHA256", hashlib.sha256(manifest).hexdigest()
)
commands = []
def run(arguments, **_kwargs):
commands.append(arguments)
if arguments[:2] == ["git", "--git-dir"]:
if "rev-parse" in arguments:
return subprocess.CompletedProcess(arguments, 0, stdout=revision, stderr="")
if "show" in arguments:
return subprocess.CompletedProcess(arguments, 0, stdout=manifest, stderr=b"")
if arguments[:3] == ["docker", "network", "ls"]:
return subprocess.CompletedProcess(
arguments, 0, stdout="itworx-mcp-hub-npm\n", stderr=""
)
if arguments[:3] == ["docker", "network", "inspect"]:
return subprocess.CompletedProcess(
arguments,
0,
stdout=json.dumps(
{"Name": "itworx-mcp-hub-npm", "Driver": "bridge", "Scope": "local"}
),
stderr="",
)
if arguments[:3] == ["docker", "ps", "-a"]:
return subprocess.CompletedProcess(arguments, 0, stdout="", stderr="")
if arguments[:3] == ["docker", "image", "inspect"]:
return subprocess.CompletedProcess(
arguments, 0, stdout="sha256:" + "d" * 64, stderr=""
)
raise AssertionError(f"unexpected fixed read-only command: {arguments!r}")
monkeypatch.setattr(status_module.subprocess, "run", run)
profile = {
"revision": revision,
"workspace_image_digest": "sha256:" + "b" * 64,
"frontdoor_image_digest": "sha256:" + "c" * 64,
}
result = status_module._forge_bootstrap_runtime_checks(profile)
assert result["status"] == "preflight_unknown"
assert result["checks"]["exact_main"] == {"status": "passed"}
assert result["checks"]["source_manifest"] == {"status": "passed"}
assert result["checks"]["managed_appdata"] == {"status": "passed"}
assert result["checks"]["proxy_network"] == {"status": "passed"}
assert result["checks"]["resource_collisions"] == {"status": "passed"}
assert result["checks"]["push_validation"] == {"status": "unknown"}
assert result["evidence"]["mainRevision"] == revision
assert result["evidence"]["sourceManifestSha256"] == hashlib.sha256(manifest).hexdigest()
assert result["evidence"]["workspaceImagePresent"] is True
assert result["evidence"]["frontdoorImagePresent"] is True
assert all(isinstance(command, list) for command in commands)
assert all("shell" not in " ".join(command).lower() for command in commands)
commands.clear()
non_head = dict(profile, revision="b" * 40)
result = status_module._forge_bootstrap_runtime_checks(non_head)
assert result["checks"]["exact_main"] == {"status": "blocked"}
assert result["status"] == "preflight_blocked"
postgres_dir.rmdir()
postgres_dir.parent.rmdir()
managed_root.rmdir()
result = status_module._forge_bootstrap_runtime_checks(profile)
assert result["checks"]["managed_appdata"] == {"status": "blocked"}
assert not managed_root.exists()
def test_forge_appdata_parent_requires_root_only_metadata(status_module, monkeypatch):
monkeypatch.setattr(status_module, "os", types.SimpleNamespace(name="posix"))
safe = types.SimpleNamespace(
st_mode=status_module.stat.S_IFDIR | 0o700, st_uid=0, st_gid=0
)
group_writable = types.SimpleNamespace(
st_mode=status_module.stat.S_IFDIR | 0o770, st_uid=0, st_gid=0
)
wrong_owner = types.SimpleNamespace(
st_mode=status_module.stat.S_IFDIR | 0o700, st_uid=1000, st_gid=0
)
assert status_module._forge_app_dir_metadata_is_safe(safe) is True
assert status_module._forge_app_dir_metadata_is_safe(group_writable) is False
assert status_module._forge_app_dir_metadata_is_safe(wrong_owner) is False
def test_forge_local_image_query_failure_is_unknown(status_module, monkeypatch):
monkeypatch.setattr(
status_module.subprocess,
"run",
lambda *_args, **_kwargs: subprocess.CompletedProcess(
[], 1, stdout="", stderr="daemon unavailable"
),
)
assert (
status_module._forge_local_image_present(
"gitea.example.com/jens/itworx-forge@sha256:" + "a" * 64
)
is None
)
@@ -0,0 +1,214 @@
from __future__ import annotations
from sqlmodel import Session, SQLModel, create_engine
from backend.app.db.models import DeploymentJob
from backend.app.schemas.enrollment import EnrollmentTrustConfigV1
from backend.app.schemas.forge_bootstrap import ForgeBootstrapPreflightV1
from backend.app.services.enrollment_plane import EnrollmentPlane
from backend.app.services.forge_bootstrap_preflight import (
ForgeBootstrapPreflightService,
)
def _profile(**overrides):
value = {
"api_version": "itworx.forge-bootstrap-preflight/v1",
"revision": "a" * 40,
"workspace_image_digest": "sha256:" + "b" * 64,
"frontdoor_image_digest": "sha256:" + "c" * 64,
}
value.update(overrides)
return ForgeBootstrapPreflightV1.model_validate(value)
def _session(tmp_path):
engine = create_engine(f"sqlite:///{tmp_path / 'forge-preflight.db'}")
SQLModel.metadata.create_all(engine)
return Session(engine)
def test_forge_profile_is_strict_and_cannot_select_runtime_inputs():
_profile()
for key, value in (
("host_path", "/etc"),
("endpoint", "https://attacker.invalid"),
("secret_ref", "OTHER_SECRET"),
("command", "docker compose up"),
("repository", "other/repo"),
("target", "other-host"),
):
try:
_profile(**{key: value})
except ValueError:
pass
else: # pragma: no cover - assertion clarity
raise AssertionError(f"caller-controlled {key} must be rejected")
for field, value in (
("revision", "a" * 39),
("workspace_image_digest", "latest"),
("frontdoor_image_digest", "sha256:" + "D" * 64),
):
try:
_profile(**{field: value})
except ValueError:
pass
else: # pragma: no cover - assertion clarity
raise AssertionError(f"invalid {field} must be rejected")
class _Broker:
def __init__(self, result):
self.result = result
self.calls = []
def forge_bootstrap_preflight(self, profile, *, secret):
self.calls.append((profile.model_dump(mode="json"), secret))
return self.result
def _trust(session, *, root="/var/lib/docker/volumes/itworx-managed-appdata/_data"):
EnrollmentPlane.set_trust_config(
session,
EnrollmentTrustConfigV1(
controller_identity="tower-deployment-controller",
bootstrap_secret_ref="CONTROLLER_BOOTSTRAP",
trusted_appdata_root=root,
managed_appdata_backup_acknowledged=(
root == "/var/lib/docker/volumes/itworx-managed-appdata/_data"
),
approved_networks=("itworx-mcp-hub-npm",),
),
)
def test_forge_preflight_uses_stored_trust_and_preserves_unknowns(tmp_path, monkeypatch):
from backend.app.services import forge_bootstrap_preflight as service_module
broker = _Broker(
{
"apiVersion": "itworx.forge-bootstrap-preflight/v1",
"status": "preflight_blocked",
"revision": "a" * 40,
"workspaceImageDigest": "sha256:" + "b" * 64,
"frontdoorImageDigest": "sha256:" + "c" * 64,
"checks": {
"exact_main": {"status": "passed"},
"source_manifest": {"status": "passed"},
"managed_appdata": {"status": "blocked"},
"proxy_network": {"status": "passed"},
"resource_collisions": {"status": "passed"},
"push_validation": {"status": "unknown"},
"image_registry": {"status": "unknown"},
"oidc": {"status": "unknown"},
"secret_delivery": {"status": "unknown"},
},
}
)
monkeypatch.setattr(service_module, "get_secret", lambda *_args, **_kwargs: "s" * 48)
monkeypatch.setattr(service_module, "has_secret", lambda *_args, **_kwargs: True)
with _session(tmp_path) as session:
_trust(session)
result = ForgeBootstrapPreflightService(broker=broker).preflight(
session, _profile(), idempotency_key="forge-preflight-test-0001"
)
assert result["status"] == "preflight_failed"
assert result["preflight"]["status"] == "blocked"
assert "push_validation" in {
item["name"] for item in result["preflight"]["checks"]
if item["status"] == "unknown"
}
assert broker.calls == [(_profile().model_dump(mode="json"), "s" * 48)]
job = session.get(DeploymentJob, result["id"])
assert job is not None
assert job.status == "preflight_failed"
assert ForgeBootstrapPreflightService().refresh(session, job.id)["id"] == job.id
assert any(item["id"] == job.id for item in ForgeBootstrapPreflightService.list_jobs(session))
def test_forge_preflight_idempotency_rejects_profile_change(tmp_path, monkeypatch):
from backend.app.services import forge_bootstrap_preflight as service_module
broker = _Broker(
{
"apiVersion": "itworx.forge-bootstrap-preflight/v1",
"status": "preflight_unknown",
"revision": "a" * 40,
"workspaceImageDigest": "sha256:" + "b" * 64,
"frontdoorImageDigest": "sha256:" + "c" * 64,
"checks": {
"exact_main": {"status": "unknown"},
"source_manifest": {"status": "unknown"},
"managed_appdata": {"status": "unknown"},
"proxy_network": {"status": "unknown"},
"resource_collisions": {"status": "unknown"},
"push_validation": {"status": "unknown"},
"image_registry": {"status": "unknown"},
"oidc": {"status": "unknown"},
"secret_delivery": {"status": "unknown"},
},
}
)
monkeypatch.setattr(service_module, "get_secret", lambda *_args, **_kwargs: "s" * 48)
monkeypatch.setattr(service_module, "has_secret", lambda *_args, **_kwargs: True)
with _session(tmp_path) as session:
_trust(session)
service = ForgeBootstrapPreflightService(broker=broker)
service.preflight(session, _profile(), idempotency_key="forge-preflight-test-0002")
replay = service.preflight(session, _profile(), idempotency_key="forge-preflight-test-0002")
assert replay["idempotentReplay"] is True
assert len(broker.calls) == 1
try:
service.preflight(
session,
_profile(revision="d" * 40),
idempotency_key="forge-preflight-test-0002",
)
except ValueError as exc:
assert "different Forge profile" in str(exc)
else: # pragma: no cover
raise AssertionError("idempotency key reuse with changed Forge profile must fail")
def test_legacy_storage_trust_still_collects_read_only_controller_blockers(tmp_path, monkeypatch):
from backend.app.services import forge_bootstrap_preflight as service_module
checks = {
name: {"status": "unknown"}
for name in (
"exact_main", "source_manifest", "managed_appdata", "proxy_network",
"resource_collisions", "push_validation", "image_registry", "oidc",
"secret_delivery",
)
}
checks["managed_appdata"] = {"status": "blocked"}
broker = _Broker(
{
"apiVersion": "itworx.forge-bootstrap-preflight/v1",
"status": "preflight_blocked",
"revision": "a" * 40,
"workspaceImageDigest": "sha256:" + "b" * 64,
"frontdoorImageDigest": "sha256:" + "c" * 64,
"checks": checks,
}
)
monkeypatch.setattr(service_module, "get_secret", lambda *_args, **_kwargs: "s" * 48)
monkeypatch.setattr(service_module, "has_secret", lambda *_args, **_kwargs: True)
with _session(tmp_path) as session:
_trust(session, root="/srv/example/appdata")
result = ForgeBootstrapPreflightService(broker=broker).preflight(
session, _profile(), idempotency_key="forge-legacy-trust-0001"
)
assert broker.calls == [(_profile().model_dump(mode="json"), "s" * 48)]
assert "managed_appdata_root_selection" in result["preflight"]["blockers"]
controller_checks = {
item["name"]: item["status"] for item in result["preflight"]["checks"]
}
assert controller_checks["managed_appdata"] == "blocked"
assert controller_checks["proxy_network"] == "unknown"
@@ -231,6 +231,59 @@ def test_n8n_uses_the_shared_grounded_knowledge_service(integration_client):
)
def test_forge_bootstrap_preflight_is_read_only_and_rejects_generic_apply(integration_client):
client, _engine = integration_client
from backend.app import mcp_server
profile = {
"api_version": "itworx.forge-bootstrap-preflight/v1",
"revision": "a" * 40,
"workspace_image_digest": "sha256:" + "b" * 64,
"frontdoor_image_digest": "sha256:" + "c" * 64,
}
response = client.post(
"/api/deployments/forge-bootstrap/preflight",
headers={**human_headers(client), "Idempotency-Key": "forge-api-preflight-0001"},
json=profile,
)
assert response.status_code == 200
result = response.json()
assert result["status"] == "preflight_failed"
assert result["preflight"]["status"] == "blocked"
assert "deployment_apply_policy" in result["preflight"]["blockers"]
assert "controller_trust" in result["preflight"]["blockers"]
refreshed = client.get(
f"/api/deployments/{result['id']}", headers=human_headers(client)
)
assert refreshed.status_code == 200
assert refreshed.json()["preflight"]["status"] == "blocked"
listed = client.get("/api/deployments", headers=human_headers(client))
assert any(item["id"] == result["id"] for item in listed.json()["items"])
generic_apply = client.post(
"/api/deployments",
headers={**human_headers(client), "Idempotency-Key": "forge-generic-apply-0001"},
json={"operation": "apply", "plan": profile},
)
assert generic_apply.status_code == 422
async def exercise_mcp():
async with Client(mcp_server.appops_mcp) as mcp_client:
preflight = await mcp_client.call_tool(
"deployment.preflight",
{"plan": profile, "idempotencyKey": "forge-mcp-preflight-0001"},
)
assert preflight.structured_content["preflight"]["status"] == "blocked"
apply = await mcp_client.call_tool(
"deployment.apply",
{"plan": profile, "idempotencyKey": "forge-mcp-apply-0001"},
)
assert apply.structured_content["status"] == "invalid"
asyncio.run(exercise_mcp())
def test_local_rag_indexes_allowlisted_docs_and_redacts_secrets(tmp_path):
from backend.app.services import knowledge_service