Skip to content

feat: Phala TDX attestation trust-root for agent-challenge (validator/master, offline-validated)#39

Merged
echobt merged 25 commits into
mainfrom
mission/phala-attest
Jul 13, 2026
Merged

feat: Phala TDX attestation trust-root for agent-challenge (validator/master, offline-validated)#39
echobt merged 25 commits into
mainfrom
mission/phala-attest

Conversation

@echobt

@echobt echobt commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Base-side (validator / master) integration for the Phala TEE (Intel TDX) attestation-rooted agent-challenge evaluation. This is the trust-root half of the cross-repo change whose miner/enclave half lives in BaseIntelligence/agent-challenge (branch mission/phala-attest, available after PR merge).

What's included (offline-validated)

  • ExecutionProof Phala tier (src/base/schemas/worker.py, src/base/worker/proof.py) — new attestation payload {tdx_quote, event_log, report_data, measurement{mrtd,rtmr0-3,compose_hash,os_image_hash}, vm_config} + single-source phala_report_data binding (tag base-agent-challenge-v1). Existing tier-0/1/2 behavior unchanged.
  • Phala quote verifier (src/base/worker/phala_quote.py, phala_verify.py) — TDX quote parse, RTMR3 event-log replay, DCAP verify with park-vs-reject split; MeasurementAllowlist (fail-closed on empty, multi-entry image rotation, fail-closed loaders). verify_execution_proof extended with a conjunctive Phala path (attestation as trust root; nonce consumed last so a park never burns it).
  • Validator adapterrebind_worker_signature replaces the lean-image placeholder signature when ingesting the attested result.
  • Master R=1 — attested agent-challenge units stay at replication factor 1 with no worker-plane replication / reconciliation / dispute / audit (proven non-vacuous against a sibling GPU unit that replicates to R=2).
  • Flag-off invariant — legacy validator-run path byte-identical; the Phala verifier is never invoked when the flag is off.
  • Cross-integration / cross-compat tests — attestation carry-chain byte-integrity across the challenge↔base JSON boundary; a shared golden TDX quote/measurement vector asserted in both repos to catch cross-repo parser drift.

Validation

uv run pytest (with BASE_TEST_DATABASE_URL), uv run mypy src tests, and ruff all clean; per-milestone scrutiny + user-testing gates passed. Base test suite green (~1860 passed).

Pending: live TDX validation

Live verification of a real TDX quote against a deployed CVM is pending the live infrastructure described in the companion agent-challenge PR (registry, public RA-TLS-fronted key-release ingress, LLM gateway).

Note: this branch is currently ~2 commits behind origin/main; a merge/rebase may be needed before final merge.


Draft PR. Commits authored as echobt.

Summary by CodeRabbit

  • New Features

    • Added opt-in Phala Intel TDX attestation support for Agent Challenge evaluations.
    • Added strict execution-proof validation, quote verification, measurement allowlists, nonce protection, and replay-audit handling.
    • Added fail-closed proxy routing that restricts attested endpoints and removes sensitive headers.
    • Added safeguards to preserve R=1 Agent Challenge behavior while supporting worker-plane evaluations separately.
  • Documentation

    • Documented attested routing, security considerations, replay audits, configuration, and legacy behavior.
  • Bug Fixes

    • Improved handling of malformed proofs, verifier outages, and invalid replay data.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1fa286ca-4744-4656-a967-a668b7e8623e

📥 Commits

Reviewing files that changed from the base of the PR and between 95c92c8 and c4ec5c0.

📒 Files selected for processing (37)
  • .gitignore
  • README.md
  • docs/architecture.md
  • docs/challenge-integration.md
  • docs/challenges.md
  • docs/master/README.md
  • docs/miner/worker-plane.md
  • docs/security.md
  • docs/validator/README.md
  • src/base/cli_app/main.py
  • src/base/config/settings.py
  • src/base/master/app_proxy.py
  • src/base/master/assignment.py
  • src/base/master/challenge_work_source.py
  • src/base/master/orchestration.py
  • src/base/master/replay_audit.py
  • src/base/schemas/worker.py
  • src/base/validator/agent/adapters/agent_challenge.py
  • src/base/worker/phala_quote.py
  • src/base/worker/phala_verify.py
  • src/base/worker/proof.py
  • tests/unit/eval_execution_proof_v2_vectors.json
  • tests/unit/phala_quote_golden_vector.json
  • tests/unit/test_agent_challenge_attested_proxy.py
  • tests/unit/test_client_service_cli_config.py
  • tests/unit/test_cross_integration_carry_chain.py
  • tests/unit/test_eval_execution_proof_v2.py
  • tests/unit/test_flag_off_invariant.py
  • tests/unit/test_master_r1_preserved.py
  • tests/unit/test_phala_quote.py
  • tests/unit/test_phala_quote_golden_vector.py
  • tests/unit/test_phala_verify.py
  • tests/unit/test_replay_audit_integration.py
  • tests/unit/test_replay_audit_schema_hardening.py
  • tests/unit/test_supervisor_weights.py
  • tests/unit/test_worker_proof_phala.py
  • tests/unit/test_worker_proof_phala_verify.py

📝 Walkthrough

Walkthrough

This change adds an opt-in Agent Challenge Phala Intel TDX attestation path, strict proof and quote verification, fail-closed proxy routing, replay-audit orchestration, and extensive unit and integration coverage while preserving legacy flag-off behavior.

Changes

Agent Challenge Phala attestation and replay audit

Layer / File(s) Summary
Attested proxy contract and configuration
.gitignore, README.md, docs/..., src/base/master/app_proxy.py, tests/unit/test_agent_challenge_attested_proxy.py
Adds the opt-in proxy flag, canonical allowlisted routes, private-route denial, sensitive-header stripping, and documentation for legacy versus attested routing.
Phala proof schema and verification
src/base/schemas/worker.py, src/base/worker/phala_quote.py, src/base/worker/phala_verify.py, src/base/worker/proof.py
Adds strict Eval proof models, TDX quote parsing, RTMR3 replay, DCAP-QVL verification, measurement allowlists, nonce validation, report-data binding, and Phala proof construction.
Replay-audit wire and orchestration
src/base/master/replay_audit.py, src/base/master/assignment.py, src/base/master/challenge_work_source.py, src/base/master/orchestration.py, src/base/validator/agent/adapters/agent_challenge.py
Adds validated replay request/result schemas, replay work-unit persistence, HTTP discovery and forwarding, orchestration bridging, durable forwarding, and replay-specific validator dispatch.
Attestation integration invariants
tests/unit/test_cross_integration_carry_chain.py, tests/unit/test_eval_execution_proof_v2.py, tests/unit/test_flag_off_invariant.py, tests/unit/test_master_r1_preserved.py
Tests byte-preserving attestation transport, strict schema limits, R=1 behavior, flag-off legacy routing, and the absence of worker-plane artifacts for Agent Challenge work.
Quote and verifier validation
tests/unit/test_phala_quote.py, tests/unit/test_phala_quote_golden_vector.py, tests/unit/test_phala_verify.py, tests/unit/test_worker_proof_phala_verify.py
Covers quote parsing, event replay, verifier parking and rejection semantics, golden vectors, allowlist loading, nonce lifecycle, replay resistance, and Phala proof acceptance.
Replay and regression coverage
tests/unit/test_replay_audit_integration.py, tests/unit/test_replay_audit_schema_hardening.py, tests/unit/test_worker_proof_phala.py, tests/unit/test_supervisor_weights.py
Validates replay wire integrity, duplicate-key and digest rejection, proof serialization and report-data vectors, and reusable scheduler log capture.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Challenge
  participant PublicProxy
  participant Master
  participant Validator
  participant DCAPQVL
  Challenge->>PublicProxy: Submit allowlisted signed review/eval request
  PublicProxy->>Master: Forward canonical request and sanitized headers
  Master->>Validator: Assign R=1 Agent Challenge work
  Validator->>DCAPQVL: Verify Phala TDX quote
  DCAPQVL-->>Validator: Return quote verdict or unavailable status
  Validator-->>Master: Return validated execution result
  Master-->>Challenge: Forward accepted replay or evaluation result
Loading
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch mission/phala-attest

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

echobt added 25 commits July 13, 2026 17:34
Add the foundational Phala tier to the shared ExecutionProof envelope so the
image emitter (M1) and validator/master verifier (M4) share one canonical
schema (architecture.md sec 6/9):

- schemas/worker.py: PHALA_TDX_TIER constant ('phala-tdx'); PhalaMeasurement
  (mrtd, rtmr0-3, compose_hash, os_image_hash) with canonical() static subset;
  PhalaAttestation payload (tdx_quote, event_log, report_data, measurement,
  vm_config) accepting the tdx_quote_b64/report_data_hex aliases. Widen
  ExecutionProof.tier to int | str so it carries the Phala value; tier 0/1/2
  behavior is unchanged.
- worker/proof.py: phala_report_data / phala_report_data_hex (sec-6 binding,
  sorted task_ids, rtmr3 excluded, 64-byte left-aligned field) and
  build_phala_execution_proof (reuses build_execution_proof; keeps the tier-0
  worker signature so verify_execution_proof still validates it).

No fork of the envelope; quote verification is layered on later (M4).
Assert phala_report_data/_hex against a fixed input -> expected 64-byte hex
that agent-challenge's self-contained sec-6 replica asserts against too, so the
two implementations cannot silently drift (VAL-IMG-012).
Validate the exact attested-result envelope the agent-challenge canonical image
emits against base's real ExecutionProof/PhalaAttestation models, and assert
per-field omission is rejected. Drift guard for VAL-IMG-025/026 (mirrors the
report_data golden-vector pin).
… test

Correct the type: ignore code from [union-attr] to [attr-defined] on the
GOLDEN_EMITTED_ENVELOPE['attestation'].items() access; mypy infers the value
as object (attr-defined), so the milestone typecheck gate (uv run mypy src tests)
was failing. No behavior change.
… reject tamper, park on outage)

Extend verify_execution_proof with a Phala-tier verifier (VAL-VERIFY-001..014):
DCAP sig/TCB via QuoteVerifier (dcap-qvl), measurement reconstructed from the
signed quote + event-log RTMR3 replay checked against a validator-owned
allowlist, report_data bound to the validator's expected (agent_hash,
sorted task_ids, scores_digest, fresh single-use nonce), and tier-0 worker
signature still enforced (no cross-unit replay). A transient verifier outage
raises VerifierUnavailableError so the caller parks (never accepts, never
fraud-rejects). The agent_challenge adapter rebinds the lean image's placeholder
worker_signature to the ingesting unit; trust root remains the attestation.
…TDX quote golden vector

M4 verify-weights scrutiny robustness follow-ups (phala_quote.py):

1. DcapQvlVerifier.verify: a returncode==0 invocation whose stdout is
   unparseable / non-JSON / missing a TCB status is a dcap-qvl *tooling*
   regression, not a fraud verdict. Map it to VerifierUnavailableError (PARK,
   retryable) instead of QuoteVerificationError (permanent reject), so a tooling
   regression cannot permanently fraud-reject a legitimate result. Genuine
   invalid-quote/bad-TCB (nonzero exit) still permanently rejects; timeout /
   missing-binary / subprocess error still parks. Never accept-any.

2. Cross-repo anti-drift: pin a shared golden TDX quote/measurement/RTMR3 vector
   (fixed quote + event-log bytes -> expected MRTD/RTMR0-3/os_image_hash/RTMR3
   compose-hash) as a byte-identical fixture asserted here and in agent-challenge
   (tests/test_quote_golden_vector.py). A one-sided offset/hash tweak to either
   parser diverges from the pinned values and fails a test on that side.
…rity

Offline complements to the agent-challenge cross-integration suite: the
master keeps attested agent-challenge units at replication factor 1 with no
worker-plane reconcile (a sibling prism gpu unit still replicates to R=2,
so the result is non-vacuous), and the TDX quote/report_data/measurement
survive the challenge<->BASE JSON boundary and validator tier-0 rebind
byte-for-byte (a single flipped byte / re-encoded report_data breaks it).
Uses a deterministic in-test signer to keep bittensor's import-time logging
reconfiguration out of the module. Covers VAL-CROSS-003 and VAL-CROSS-007 (base leg).
The scheduler error-log test only restored the logger's .disabled flag, so a
bittensor import (forces existing loggers to CRITICAL) or alembic fileConfig
(logging.disable) run earlier in the process silenced the ERROR record and
failed the test only in the full alphabetical suite. Snapshot and neutralize
logging.disable, the scheduler logger's .disabled/.level/.propagate in a
fixture, capture on its own logger, then restore. Assertions unchanged (a
compute raise is logged and the schedule keeps ticking).
…-021)

With the flag OFF the master bridges an attested agent-challenge submission
exactly like legacy: cpu units at R=1, no worker plane / reconciliation, and
the legacy reassign-on-failure (never replicate) path (owner crash -> revert
-> reassign to a different validator, +1 attempt, zero worker replicas). The
sibling gpu R=2 replica in VAL-CROSS-003 keeps this non-vacuous. bittensor-free
(reuses the file's fixtures) to avoid the supervisor-weights log-test ordering
hazard.
Replace the attested agent-challenge deny-list residual fallthrough with an
explicit enabled-mode allowlist so capability, assignment, evidence, key-release,
direct-result, and results aliases 404 before any upstream call while status,
events, benchmark, and signed review/eval routes remain forwardable.
Align EVAL_MAX_VM_CONFIG_BYTES with contract eval_result_max_vm_config_bytes
and exercise the one-over budget via closed three-field encoding.
Mirror agent-challenge: live TDX quote hex is not a path argument for
dcap-qvl and trips "File name too long" when passed on argv.
…ted)

Assert full-attested mode creates zero agent-challenge master assignment/
replica rows (empty challenge work feed), while sibling prism GPU R=2 stays
non-vacuous for the worker plane.
Call out Phala-tier proof carry, R=1 for attested units, and public-proxy
deny rules so agent-challenge result routes stay challenge-direct.
Document BASE-owned ExecutionProof Phala tier, failing-closed public proxy allowlist, R=1 full-attested path, and security residual risks without inventing challenge-side behavior.
Keep Phala-tier verifier functions while using main's challenge_sdk proof
helpers after the rebase onto Swarm main.
Use digest-pinned challenge images and current assignment core fields
after rebasing Phala attestation commits onto main.
@echobt echobt force-pushed the mission/phala-attest branch from b0d1cb4 to c4ec5c0 Compare July 13, 2026 17:41
@echobt echobt marked this pull request as ready for review July 13, 2026 17:46
@echobt echobt merged commit e269862 into main Jul 13, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant