Add a Trust Center Widget to your ERC-8004 Agent

October 29, 2025
5 min read
Add a Trust Center Widget to your ERC-8004 Agent

What this post is: a short, copy-paste technical walkthrough showing how PR #5 adds a Trust Center widget to the erc-8004-tee-agent UI, how to enable it in a VibeVM (env / docker-compose), and how to test the enabled vs disabled behavior. This guide uses the PR as an example implementation you can run in your Phala Cloud VibeVM.


TL;DR (30s)

  • PR adds a floating Trust Center widget + modal iframe in the frontend and a backend endpoint /api/trust-center-url that returns the configured widget URL (or 404 when disabled).
  • Enable with an env var: TRUST_CENTER_URL=https://trust.phala.com/widget/app/<dstack-app-id>.
  • Test quickly with curl and by loading the app UI — widget appears when enabled, disappears when unset.

Why add a Trust Center widget?

A small in-app widget gives users immediate, discoverable access to attestation/verification information (the Trust Center) without leaving the app. For TEE-backed agents this improves UX and trust signals: users can inspect attestations, key provenance, and governance info directly from the agent UI. The implementation below is designed to be opt-in (env toggle) and minimal attack surface (iframe + backend echo endpoint).


What changed in the PR

Key pieces implemented in PR #5:

  • Backend: new route /api/trust-center-url that reads TRUST_CENTER_URL from env and returns JSON { "trust_center_url": "<url>" } when set, or HTTP 404 when not configured.
  • Frontend: trust-center.js component that injects a small floating widget; clicking it opens a modal with an iframe pointed at the value returned by /api/trust-center-url.
  • Config: .env.example updated with TRUST_CENTER_URL placeholder; docker-compose.yml updated to pass the env through.
  • UI & CSS: minimal floating control and modal styling.

(See PR: https://github.com/Phala-Network/erc-8004-tee-agent/pull/5)


Quick config & code snippets

.env example (enable the widget)

# enable the Trust Center widget (production/staging)
TRUST_CENTER_URL=https://trust.phala.com/widget/app/<dstack-app-id>

docker-compose.yml excerpt (pass env)

services:
	# Other container info
  agent:
    image: ubuntu:22.04
    platform: linux/amd64
    container_name: erc8004-agent
    environment:
      - TRUST_CENTER_URL=${TRUST_CENTER_URL:-https://trust.phala.com/widget/app/${DSTACK_APP_ID}}
      # Other env vars and command
    ports:
      - "8000:8000"

Backend (conceptual Python/Flask snippet)

# /api/trust-center-url
from flask import Flask, jsonify, abort
import os

app = Flask(__name__)

@app.get("/api/trust-center-url")
def trust_center_url():
    url = os.getenv("TRUST_CENTER_URL", "").strip()
    if not url:
        abort(404)
    return jsonify({"trust_center_url": url})

Frontend (conceptual widget component)

// trust-center.js (simplified)
async function fetchTrustUrl() {
  const res = await fetch("/api/trust-center-url");
  if (!res.ok) return null;
  const { trust_center_url } = await res.json();
  return trust_center_url;
}

async function initTrustWidget() {
  const url = await fetchTrustUrl();
  if (!url) return; // widget disabled
  // render floating button; open modal with <iframe src="{url}" sandbox="allow-scripts allow-same-origin">
}
Keep the iframe sandboxed and enforce a CSP that restricts framing origins to trust.phala.com if possible.

Deploy & reproduce (step-by-step)

  1. cd into the erc-8004-tee-agent folder and apply the changes locally in VibeVM:
    cd erc-8004-tee-agent
    git switch feat/trust-center
    
  2. Enable widget:
    cp .env.example .env
    # edit .env -> set TRUST_CENTER_URL=https://trust.phala.com
    
  3. Install dependencies and deploy locally in VibeVM:
    pip install -e .
    python deployment/local_agent_server.py
    
  4. Verify backend behavior:
    • Enabled:
      curl -sS http://<dstack-app-id>-8000.<dstack-gateway-domain>/api/trust-center-url
      # Ex. curl https://6ff54f6770a95e28ed7b9bba1460b09b0f35c0e4-8000.dstack-pha-prod9.phala.network/api/trust-center-url
      # {"trust_center_url":"https://trust.phala.com/widget/app/6ff54f6770a95e28ed7b9bba1460b09b0f35c0e4"}

    • Go to the TRUST_CENTER_URL in the browser
  5. Open the app UI (e.g., https://<dstack-app-id>-8000.<dstack-gateway-domain> ):
    • With TRUST_CENTER_URL set: confirm the floating widget appears. Click it → modal opens an iframe to https://trust.phala.com.
    • With TRUST_CENTER_URL unset: widget not present.
  6. Staging checks:
    • Test behind your staging reverse proxy to ensure CSP/frame-ancestors behave correctly.
    • Confirm /api/trust-center-url only echoes a server-side configuration value — never accept or render arbitrary client-supplied URLs.

Security & UX checklist (short)

  • Iframe sandbox: use sandbox attribute (allow-scripts only if necessary) and avoid allow-top-navigation.
  • CSP: add frame-ancestors 'self' https://trust.phala.com and other header protections.
  • Server-side control: the endpoint must only return the configured URL; do not accept a query param or request body URL.
  • Privacy: Trust Center pages should not capture or leak user tokens; the widget is a navigational/trust surface, not a data channel.

Test matrix (quick)

  • Unit: endpoint returns JSON when set; 404 when empty.
  • Integration: widget renders when endpoint returns URL.
  • Manual: click widget → iframe loads trust.phala.com and presents attestation UI.

Resources & next steps

Call to action: Add more trust to your agents and enable the Trust Center widget in your VibeVM, run the tests above.


Recent Posts

Related Posts