Record privileged action failure evidence
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a0217e-8c4c-7383-be6b-f50a6e485306
This commit is contained in:
parent
c4504c6de9
commit
f579f3761c
8 changed files with 517 additions and 189 deletions
|
|
@ -16,6 +16,7 @@ from datetime import datetime, timezone
|
|||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from secrets_engine.errors import DecisionError, SecretsEngineError
|
||||
from secrets_engine.redact import looks_secret, redact_text
|
||||
|
||||
# Keys that must never carry a value into evidence regardless of nesting.
|
||||
|
|
@ -143,3 +144,88 @@ class EvidenceWriter:
|
|||
except (urllib.error.URLError, OSError, ValueError):
|
||||
# Hub being offline must never block secret work or leak anything.
|
||||
return "failed"
|
||||
|
||||
|
||||
@dataclass
|
||||
class PrivilegedActionEvidence:
|
||||
"""Record one privileged command's attempt, approval, and terminal result."""
|
||||
|
||||
writer: EvidenceWriter
|
||||
action: str
|
||||
catalog_id: str
|
||||
stage: str
|
||||
decision_ref: str = ""
|
||||
approval_required: bool = False
|
||||
detail: dict[str, Any] = field(default_factory=dict)
|
||||
decision_id: str = ""
|
||||
approval_status: str = "pending"
|
||||
completed: bool = False
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
if not self.approval_required:
|
||||
self.approval_status = "not-required"
|
||||
|
||||
def _detail(self, extra: dict[str, Any] | None = None) -> dict[str, Any]:
|
||||
merged = dict(self.detail)
|
||||
merged.update(
|
||||
{
|
||||
"approval_status": self.approval_status,
|
||||
"decision_ref": self.decision_ref,
|
||||
}
|
||||
)
|
||||
if extra:
|
||||
merged.update(extra)
|
||||
return merged
|
||||
|
||||
def __enter__(self) -> "PrivilegedActionEvidence":
|
||||
self.writer.record(
|
||||
self.action,
|
||||
result="attempt",
|
||||
catalog_id=self.catalog_id,
|
||||
stage=self.stage,
|
||||
detail=self._detail(),
|
||||
)
|
||||
return self
|
||||
|
||||
def mark_approved(self, decision: object | None) -> None:
|
||||
if decision is None:
|
||||
self.approval_status = "not-required"
|
||||
return
|
||||
self.decision_id = str(getattr(decision, "id", ""))
|
||||
self.approval_status = "approved"
|
||||
|
||||
def finish(
|
||||
self, result: str, *, detail: dict[str, Any] | None = None
|
||||
) -> dict[str, Any]:
|
||||
self.completed = True
|
||||
return self.writer.record(
|
||||
self.action,
|
||||
result=result,
|
||||
catalog_id=self.catalog_id,
|
||||
stage=self.stage,
|
||||
decision_id=self.decision_id,
|
||||
detail=self._detail(detail),
|
||||
)
|
||||
|
||||
def __exit__(self, exc_type, exc, _traceback) -> bool:
|
||||
if exc_type is None:
|
||||
if not self.completed:
|
||||
self.finish("failed-incomplete")
|
||||
return False
|
||||
if isinstance(exc, DecisionError):
|
||||
self.approval_status = "rejected"
|
||||
if isinstance(exc, (KeyboardInterrupt, SystemExit)):
|
||||
result = "interrupted"
|
||||
elif isinstance(exc, SecretsEngineError):
|
||||
result = f"failed-{type(exc).__name__}"
|
||||
else:
|
||||
result = "failed-unexpected"
|
||||
self.writer.record(
|
||||
self.action,
|
||||
result=result,
|
||||
catalog_id=self.catalog_id,
|
||||
stage=self.stage,
|
||||
decision_id=self.decision_id,
|
||||
detail=self._detail({"error_type": type(exc).__name__}),
|
||||
)
|
||||
return False
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue