Land the sanitized WH-ENG-20260822-AUDIT-E2-03 report, mark the engagement completed and terminal, and close the applicable E2 harness and risk-nexus delivery tasks. flex-auth stays pending; tenant-engine stays not_applicable. Assistant: grok Assistant-Session: 01a02670-3345-76f2-a014-70fde8e2a2bb
125 lines
4.7 KiB
Python
125 lines
4.7 KiB
Python
import json
|
|
from datetime import UTC, datetime
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from whitehat_security.engagement import AuthorizationError, Engagement
|
|
|
|
|
|
def record():
|
|
return {
|
|
"engagement_id": "WH-ENG-1", "authorization_id": "auth-1",
|
|
"authorizer": "operator", "approved_at": "2026-08-21T08:00:00Z",
|
|
"expires_at": "2026-08-21T12:00:00Z", "target": "https://fixture.invalid",
|
|
"target_owner": "target-repo", "environment": "build", "source": "runner",
|
|
"routes": ["GET /objects/{id}"], "fixture_ids": ["object-a", "object-b"],
|
|
"credential_lane": "openbao", "credential_role": "runtime",
|
|
"credential_max_ttl_seconds": 900, "techniques": ["e2-differential"],
|
|
"prohibited_techniques": ["saturation"], "rate_limit_per_minute": 10,
|
|
"max_concurrency": 1, "window_start": "2026-08-21T08:00:00Z",
|
|
"window_end": "2026-08-21T10:00:00Z", "operator_contact": "operator",
|
|
"abort_contact": "target-owner", "posture_claim": "E2",
|
|
"attacker_model": "E2-authenticated-tenant-a", "finding_destination": "risk-nexus",
|
|
"target_owner_acknowledged_at": "2026-08-21T08:01:00Z",
|
|
}
|
|
|
|
|
|
def load(tmp_path, data):
|
|
path = tmp_path / "engagement.json"
|
|
path.write_text(json.dumps(data), encoding="utf-8")
|
|
return Engagement.load(path, now=datetime(2026, 8, 21, 9, tzinfo=UTC))
|
|
|
|
|
|
def test_complete_current_record_is_accepted(tmp_path):
|
|
engagement = load(tmp_path, record())
|
|
engagement.permits(technique="e2-differential", route="GET /objects/{id}")
|
|
|
|
|
|
@pytest.mark.parametrize("field", ["target_owner_acknowledged_at", "abort_contact", "fixture_ids"])
|
|
def test_incomplete_record_fails_closed(tmp_path, field):
|
|
data = record()
|
|
del data[field]
|
|
with pytest.raises(AuthorizationError):
|
|
load(tmp_path, data)
|
|
|
|
|
|
def test_expired_record_fails_closed(tmp_path):
|
|
with pytest.raises(AuthorizationError, match="outside"):
|
|
Engagement.load(
|
|
_write(tmp_path, record()), now=datetime(2026, 8, 21, 13, tzinfo=UTC)
|
|
)
|
|
|
|
|
|
def test_unauthorized_route_fails_closed(tmp_path):
|
|
engagement = load(tmp_path, record())
|
|
with pytest.raises(AuthorizationError, match="route"):
|
|
engagement.permits(technique="e2-differential", route="DELETE /objects/{id}")
|
|
|
|
|
|
def test_pending_owner_acknowledgement_fails_closed(tmp_path):
|
|
data = record()
|
|
data["target_owner_acknowledged_at"] = None
|
|
with pytest.raises(AuthorizationError, match="pending"):
|
|
load(tmp_path, data)
|
|
|
|
|
|
def test_retry_record_is_authorized_only_inside_its_window(tmp_path):
|
|
data = json.loads(Path("engagements/2026-08-22-audit-core-e2-02.json").read_text())
|
|
data["status"] = "approved"
|
|
data.pop("aborted_at", None)
|
|
data.pop("abort_reason", None)
|
|
path = tmp_path / "retry.json"
|
|
path.write_text(json.dumps(data), encoding="utf-8")
|
|
with pytest.raises(AuthorizationError, match="has not started"):
|
|
Engagement.load(path, now=datetime(2026, 8, 22, 19, 14, tzinfo=UTC))
|
|
engagement = Engagement.load(path, now=datetime(2026, 8, 22, 19, 15, tzinfo=UTC))
|
|
assert engagement.raw["engagement_id"] == "WH-ENG-20260822-AUDIT-E2-02"
|
|
with pytest.raises(AuthorizationError, match="outside"):
|
|
Engagement.load(path, now=datetime(2026, 8, 22, 19, 31, tzinfo=UTC))
|
|
|
|
|
|
def test_aborted_record_fails_closed():
|
|
with pytest.raises(AuthorizationError, match="aborted"):
|
|
Engagement.load(
|
|
"engagements/2026-08-22-audit-core-e2-02.json",
|
|
now=datetime(2026, 8, 22, 19, 20, tzinfo=UTC),
|
|
)
|
|
|
|
|
|
def test_completed_record_fails_closed():
|
|
with pytest.raises(AuthorizationError, match="completed"):
|
|
Engagement.load(
|
|
"engagements/2026-08-22-audit-core-e2-03.json",
|
|
now=datetime(2026, 8, 22, 22, 10, tzinfo=UTC),
|
|
)
|
|
|
|
|
|
def test_elapsed_record_fails_closed_even_inside_old_window(tmp_path):
|
|
data = record()
|
|
data["status"] = "expired"
|
|
with pytest.raises(AuthorizationError, match="elapsed"):
|
|
load(tmp_path, data)
|
|
|
|
|
|
def test_proposed_record_fails_closed_before_window_checks(tmp_path):
|
|
data = record()
|
|
data["status"] = "proposed"
|
|
data["approved_at"] = None
|
|
data["target_owner_acknowledged_at"] = None
|
|
with pytest.raises(AuthorizationError, match="proposed"):
|
|
load(tmp_path, data)
|
|
|
|
|
|
def test_cancelled_record_fails_closed_even_with_owner_acknowledgement(tmp_path):
|
|
data = record()
|
|
data["status"] = "cancelled"
|
|
data["cancelled_at"] = "2026-08-21T08:02:00Z"
|
|
with pytest.raises(AuthorizationError, match="cancelled"):
|
|
load(tmp_path, data)
|
|
|
|
|
|
def _write(tmp_path, data):
|
|
path = tmp_path / "engagement.json"
|
|
path.write_text(json.dumps(data), encoding="utf-8")
|
|
return path
|