Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ build/
plan/

.omo/
*.env
secrets/
*.pem
*.key
66 changes: 63 additions & 3 deletions src/base/schemas/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from datetime import datetime
from typing import Any

from pydantic import BaseModel, Field
from pydantic import AliasChoices, BaseModel, ConfigDict, Field


class WorkerFaultView(BaseModel):
Expand Down Expand Up @@ -137,6 +137,63 @@ class WorkerSignature(BaseModel):
sig: str


#: Tier value marking an ExecutionProof as a Phala Intel TDX attestation
#: (architecture.md sec 6). Distinct from the integer worker-plane tiers so the
#: Phala envelope is self-describing without disturbing tier 0/1/2.
PHALA_TDX_TIER = "phala-tdx"


class PhalaMeasurement(BaseModel):
"""TDX measurement registers for a canonical Phala eval image (arch sec 6/7).

The static, allowlist-pinnable ``canonical_measurement`` is the subset
``{mrtd, rtmr0, rtmr1, rtmr2, compose_hash, os_image_hash}``. ``rtmr3`` is the
runtime event-log register (it carries the live compose-hash event); it is
kept on the record for completeness but excluded from the pinned canonical
measurement bound into ``report_data``.
"""

mrtd: str
rtmr0: str
rtmr1: str
rtmr2: str
rtmr3: str
compose_hash: str
os_image_hash: str

def canonical(self) -> dict[str, str]:
"""The static, allowlist-pinnable subset (excludes runtime ``rtmr3``)."""

return {
"mrtd": self.mrtd,
"rtmr0": self.rtmr0,
"rtmr1": self.rtmr1,
"rtmr2": self.rtmr2,
"compose_hash": self.compose_hash,
"os_image_hash": self.os_image_hash,
}


class PhalaAttestation(BaseModel):
"""Phala Intel TDX attestation payload carried by a Phala-tier ExecutionProof.

Populates the ``attestation`` block of an ExecutionProof whose ``tier`` is
:data:`PHALA_TDX_TIER` (architecture.md sec 6). The architecture's
``tdx_quote_b64`` / ``report_data_hex`` spellings are accepted as input
aliases; serialization always uses the canonical field names.
"""

model_config = ConfigDict(populate_by_name=True)

tdx_quote: str = Field(validation_alias=AliasChoices("tdx_quote", "tdx_quote_b64"))
event_log: list[dict[str, Any]] = Field(default_factory=list)
report_data: str = Field(
validation_alias=AliasChoices("report_data", "report_data_hex")
)
measurement: PhalaMeasurement
vm_config: dict[str, Any] = Field(default_factory=dict)


class ExecutionProof(BaseModel):
"""Proof envelope attached to every worker result (architecture 3.4).

Expand All @@ -145,11 +202,14 @@ class ExecutionProof(BaseModel):
pinned message (``sha256(f"{manifest_sha256}:{unit_id}")``). Tier 1 adds
``image_digest`` + a populated ``provider`` block; tier 2 adds a non-null
``attestation``. The base worker plane emits tier 0; prism fills the higher
tiers.
tiers. The Phala TDX tier (``tier == PHALA_TDX_TIER``) carries a
:class:`PhalaAttestation` payload in ``attestation`` (architecture.md sec 6);
hence ``tier`` accepts the string Phala value in addition to the integer
worker-plane tiers.
"""

version: int = 1
tier: int = 0
tier: int | str = 0
manifest_sha256: str
image_digest: str | None = None
provider: ProviderInfo | None = None
Expand Down
42 changes: 41 additions & 1 deletion src/base/validator/agent/adapters/agent_challenge.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@
from collections.abc import Awaitable, Callable, Mapping
from typing import Any

from base.schemas.worker import PHALA_TDX_TIER, ExecutionProof, WorkerSignature
from base.validator.agent.executor import (
AssignmentContext,
AssignmentExecutionError,
ExecutionResult,
ProgressCallback,
)
from base.validator.agent.signing import RequestSigner
from base.worker.proof import execution_proof_signing_payload

CHALLENGE_SLUG = "agent-challenge"

Expand Down Expand Up @@ -58,4 +61,41 @@ def _load_dispatch() -> DispatchFn:
return dispatch_assignment


__all__ = ["CHALLENGE_SLUG", "AgentChallengeCycleExecutor"]
def rebind_worker_signature(
proof: ExecutionProof, *, signer: RequestSigner, unit_id: str
) -> ExecutionProof:
"""Rebind a Phala-tier envelope's tier-0 worker signature to ``unit_id``.

The canonical eval image runs a LEAN CVM image with no bittensor/sr25519
keypair, so its emitted Phala-tier ``ExecutionProof`` carries only a
schema-valid PLACEHOLDER ``worker_signature`` (empty pubkey/sig). When the
validator ingests the attested ``BASE_BENCHMARK_RESULT`` payload it re-signs
the tier-0 layer over the pinned ``sha256(f"{manifest_sha256}:{unit_id}")``
message with its OWN signer, so ``verify_execution_proof`` enforces a real
signature bound to this unit (no cross-unit replay, VAL-VERIFY-013).

The trust root remains the **attestation** (the hardware-signed TDX quote),
which the validator verifies cryptographically; this rebind only anchors the
worker-plane envelope layer to a real key -- it never substitutes for quote
verification. The attestation payload is carried through unchanged.
"""

if proof.tier != PHALA_TDX_TIER:
raise AssignmentExecutionError(
"rebind_worker_signature only applies to Phala-tier proofs"
)
signature = signer.sign(
execution_proof_signing_payload(
manifest_sha256=proof.manifest_sha256, unit_id=unit_id
)
)
return proof.model_copy(
update={
"worker_signature": WorkerSignature(
worker_pubkey=signer.hotkey, sig=signature
)
}
)


__all__ = ["CHALLENGE_SLUG", "AgentChallengeCycleExecutor", "rebind_worker_signature"]
Loading
Loading