- approval_payload: kanonischer, deterministischer Approval-Payload - approval_signature: Ed25519 sign/verify (Christian=Private Key, Executor=Public Key only) - approval_verifier: verify-only, alle Bindings fail-closed - approval_state: Lifecycle CREATED->CONSUMED, Single-Use, Reservation, OUTCOME_UNKNOWN - test_approval_auth3d: T1-T30 + adversarial (50 Tests) - test_approval_helpers: synthetische Test-Keypairs - sensitivity_proof: Mutationen A-J machen Tests ROT Nur synthetische Test-Keypairs. Kein produktives Deployment. DELETE_OPERATION_ACTIVATION bleibt BLOCKED bis AUTH.3D geprueft.
101 lines
3.2 KiB
Python
101 lines
3.2 KiB
Python
"""
|
|
AUTH.3D — test_approval_helpers.py
|
|
Gemeinsame Test-Helper: synthetische Keypairs, kanonische Payloads, Zeitgeber.
|
|
|
|
NUR synthetische Test-Keypairs. KEINE echten Keys.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import datetime
|
|
import uuid
|
|
from typing import Any, Dict
|
|
|
|
from approval_payload import build_payload
|
|
from approval_signature import generate_test_keypair, key_id, sign
|
|
|
|
# Feste Test-Referenzzeit (UTC)
|
|
REF_TIME = datetime.datetime(2026, 8, 27, 12, 0, 0, tzinfo=datetime.timezone.utc)
|
|
|
|
|
|
def make_iso(dt: datetime.datetime) -> str:
|
|
return dt.strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
|
|
|
|
def now_iso() -> str:
|
|
return make_iso(REF_TIME)
|
|
|
|
|
|
def future_iso(minutes: int = 60) -> str:
|
|
return make_iso(REF_TIME + datetime.timedelta(minutes=minutes))
|
|
|
|
|
|
def past_iso(minutes: int = 60) -> str:
|
|
return make_iso(REF_TIME - datetime.timedelta(minutes=minutes))
|
|
|
|
|
|
def make_payload(
|
|
*,
|
|
approval_id: str = None,
|
|
mission_id: str = None,
|
|
delete_request_id: str = None,
|
|
object_id: str = None,
|
|
vault_path: str = "/vault/obj-a.md",
|
|
expected_commit: str = "a" * 40,
|
|
expected_provenance_hash: str = "b" * 64,
|
|
nonce: str = None,
|
|
issued_at: str = None,
|
|
expires_at: str = None,
|
|
**overrides,
|
|
) -> Dict[str, Any]:
|
|
"""Baut einen gültigen kanonischen Payload (Defaults gültig)."""
|
|
return build_payload(
|
|
approval_id=approval_id or str(uuid.uuid4()),
|
|
mission_id=mission_id or str(uuid.uuid4()),
|
|
delete_request_id=delete_request_id or str(uuid.uuid4()),
|
|
object_id=object_id or str(uuid.uuid4()),
|
|
vault_path=vault_path,
|
|
expected_commit=expected_commit,
|
|
expected_provenance_hash=expected_provenance_hash,
|
|
nonce=nonce or str(uuid.uuid4()),
|
|
issued_at=issued_at or now_iso(),
|
|
expires_at=expires_at or future_iso(),
|
|
**overrides,
|
|
)
|
|
|
|
|
|
def make_signed_approval(private_key, payload: Dict[str, Any]):
|
|
"""Signiert einen Payload und liefert (payload, signature, key_id)."""
|
|
sig = sign(private_key, payload)
|
|
return payload, sig, key_id(private_key.public_key())
|
|
|
|
|
|
def make_valid_approval(private_key, **payload_overrides):
|
|
"""Baut + signiert eine gültige Approval. Liefert (payload, sig, key_id)."""
|
|
payload = make_payload(**payload_overrides)
|
|
return make_signed_approval(private_key, payload)
|
|
|
|
|
|
def make_verifier(public_key, revoked_key_ids=None, now_fn=None):
|
|
"""Baut einen ApprovalVerifier mit einem Public Key."""
|
|
from approval_verifier import ApprovalVerifier
|
|
|
|
kid = key_id(public_key)
|
|
return ApprovalVerifier(
|
|
public_keys={kid: public_key},
|
|
revoked_key_ids=revoked_key_ids,
|
|
now_fn=now_fn or (lambda: REF_TIME),
|
|
)
|
|
|
|
|
|
def make_expected(payload: Dict[str, Any]) -> Dict[str, str]:
|
|
"""Erwartete Kontext-Werte aus einem Payload (für verify_approval)."""
|
|
return {
|
|
"expected_mission_id": payload["mission_id"],
|
|
"expected_delete_request_id": payload["delete_request_id"],
|
|
"expected_object_id": payload["object_id"],
|
|
"expected_vault_path": payload["vault_path"],
|
|
"expected_commit": payload["expected_commit"],
|
|
"expected_provenance_hash": payload["expected_provenance_hash"],
|
|
"expected_nonce": payload["nonce"],
|
|
}
|