33
44# PrivateClaw CLI
55# TEE verification and management for PrivateClaw CVMs.
6- # https://github.com/lunal-dev/privateclaw-cli
6+ # https://github.com/lunal-dev/privateclaw-cli (repo name unchanged)
77
88ATTEST_DIR=" /etc/privateclaw"
99EVIDENCE_FILE=" $ATTEST_DIR /evidence.json"
@@ -18,6 +18,8 @@ ATTESTATION_CLI="${ATTESTATION_CLI_PATH:-}"
1818if [ -z " $ATTESTATION_CLI " ]; then
1919 if command -v attestation-cli & > /dev/null; then
2020 ATTESTATION_CLI=" attestation-cli"
21+ elif [ -x /opt/confidential-services/attestation-cli ]; then
22+ ATTESTATION_CLI=" /opt/confidential-services/attestation-cli"
2123 elif [ -x /opt/lunal-services/attestation-cli ]; then
2224 ATTESTATION_CLI=" /opt/lunal-services/attestation-cli"
2325 fi
@@ -361,17 +363,27 @@ cmd_verify() {
361363 FAIL_COUNT=$(( FAIL_COUNT + 1 ))
362364 echo " "
363365 else
364- ENDPOINT=$( jq -r ' .models.providers.lunal.baseUrl // "not configured"' " $OC_CONFIG " 2> /dev/null || echo " not configured" )
366+ # Try "confidential" provider first, fall back to legacy "lunal" for older configs
367+ ENDPOINT=$( jq -r ' .models.providers.confidential.baseUrl // .models.providers.lunal.baseUrl // "not configured"' " $OC_CONFIG " 2> /dev/null || echo " not configured" )
365368 echo " Endpoint: $ENDPOINT "
366369
370+ # Read bearer token from openclaw config (apiKey field)
371+ BEARER_TOKEN=$( jq -r ' .models.providers.confidential.apiKey // .models.providers.lunal.apiKey // empty' " $OC_CONFIG " 2> /dev/null || true)
372+
367373 # Make a minimal request to the inference endpoint and capture response headers
368374 INF_HEADERS=" "
369375 if [ " $ENDPOINT " != " not configured" ]; then
370376 # NOTE: Do NOT use `curl -I -X POST` — `-I` forces HEAD which conflicts
371377 # with `-X POST` and curl bails out producing no output. Use `-D -` to
372378 # dump headers from a real GET request instead. The /v1/models endpoint
373379 # returns the same Attestation-Report header as /chat/completions.
374- INF_HEADERS=$( curl -s -D - -o /dev/null " $ENDPOINT /models" \
380+ # -k: accept self-signed TLS cert on gateway; the attestation headers
381+ # (VCEK chain) provide the real trust anchor, not TLS cert validation.
382+ CURL_AUTH_ARGS=()
383+ if [ -n " $BEARER_TOKEN " ] && [ " $BEARER_TOKEN " != " not-needed" ]; then
384+ CURL_AUTH_ARGS=(-H " Authorization: Bearer $BEARER_TOKEN " )
385+ fi
386+ INF_HEADERS=$( curl -s -k -D - -o /dev/null " ${CURL_AUTH_ARGS[@]} " " $ENDPOINT /models" \
375387 --max-time 10 2> /dev/null) || true
376388 fi
377389
@@ -385,10 +397,10 @@ cmd_verify() {
385397 echo " Status: WARN"
386398 FAIL_COUNT=$(( FAIL_COUNT + 1 ))
387399 elif [ -n " $ATTESTATION " ] || [ -n " $ORCH_ATTESTATION " ]; then
388- echo " Provider: ${INF_PROVIDER:- lunal } "
400+ echo " Provider: ${INF_PROVIDER:- confidential } "
389401
390- # --- Lunal upstream attestation (Attestation-Report, passed through untouched by our tee-proxy) ---
391- # Support two formats Lunal may send:
402+ # --- Confidential AI upstream attestation (Attestation-Report, passed through untouched by our tee-proxy) ---
403+ # Support two formats Confidential AI may send:
392404 # 1. base64+gzip (old standalone attestation inline mode)
393405 # 2. raw JSON from attestation-service sidecar: {"platform":..., "evidence":{...}}
394406 # attestation-cli verify expects the .evidence sub-object (or the whole object
@@ -415,7 +427,7 @@ cmd_verify() {
415427 fi
416428 # Try 3: base64+gzip → raw HCLA binary (Azure HCL Attestation Report)
417429 # Format: 8-byte header + "HCLA" magic (hex 48434c41) + SNP report + embedded PEM certs.
418- # Lunal 's tee-proxy sends this format directly — NOT the attestation-service JSON format.
430+ # Confidential AI 's tee-proxy sends this format directly — NOT the attestation-service JSON format.
419431 # We extract the embedded VCEK/ASK/ARK cert chain and verify with openssl.
420432 if [ " $INF_DECODED " = " false" ] && [ -s " $INF_BIN_FILE " ]; then
421433 HCLA_MAGIC=$( dd if=" $INF_BIN_FILE " bs=1 skip=8 count=4 2> /dev/null | xxd -p 2> /dev/null || true)
@@ -442,15 +454,15 @@ PYEOF
442454 cat " $INF_ASK_PEM " " $INF_ARK_PEM " > " $INF_CHAIN_PEM "
443455 VCEK_VERIFY=$( openssl verify -CAfile " $INF_CHAIN_PEM " " $INF_VCEK_PEM " 2>&1 ) || true
444456 if echo " $VCEK_VERIFY " | grep -q " : OK" ; then
445- echo " Lunal Upstream VCEK Chain: VALID (AMD root CA -> ASK -> VCEK)"
457+ echo " Confidential AI Upstream VCEK Chain: VALID (AMD root CA -> ASK -> VCEK)"
446458 INF_ATTEST_OK=true
447459 INF_DECODED=true
448460 else
449- echo " Lunal Upstream Attestation: HCLA binary present but cert chain invalid"
461+ echo " Confidential AI Upstream Attestation: HCLA binary present but cert chain invalid"
450462 echo " openssl: $VCEK_VERIFY "
451463 fi
452464 else
453- echo " Lunal Upstream Attestation: HCLA binary present but could not extract PEM certs"
465+ echo " Confidential AI Upstream Attestation: HCLA binary present but could not extract PEM certs"
454466 fi
455467 rm -f " $INF_VCEK_PEM " " $INF_ASK_PEM " " $INF_ARK_PEM " " $INF_CHAIN_PEM "
456468 fi
@@ -462,26 +474,26 @@ PYEOF
462474 if [ -n " $INF_VERIFY_RESULT " ] && echo " $INF_VERIFY_RESULT " | jq -e . & > /dev/null; then
463475 INF_SIG_VALID=$( echo " $INF_VERIFY_RESULT " | jq -r ' .signature_valid // false' )
464476 INF_PLATFORM=$( echo " $INF_VERIFY_RESULT " | jq -r ' .platform // "unknown"' )
465- echo " Lunal Platform: $INF_PLATFORM (upstream inference cluster)"
477+ echo " Confidential AI Platform: $INF_PLATFORM (upstream inference cluster)"
466478 if [ " $INF_SIG_VALID " = " true" ]; then
467- echo " Lunal Upstream VCEK Chain: VALID (AMD root CA -> VCEK -> SNP report)"
479+ echo " Confidential AI Upstream VCEK Chain: VALID (AMD root CA -> VCEK -> SNP report)"
468480 INF_ATTEST_OK=true
469481 else
470- echo " Lunal Upstream Attestation: INVALID (signature verification failed)"
482+ echo " Confidential AI Upstream Attestation: INVALID (signature verification failed)"
471483 fi
472484 else
473- echo " Lunal Upstream Attestation: present but verification failed"
485+ echo " Confidential AI Upstream Attestation: present but verification failed"
474486 fi
475487 else
476- echo " Lunal Upstream Attestation: present but no verifier (attestation-cli not found)"
488+ echo " Confidential AI Upstream Attestation: present but no verifier (attestation-cli not found)"
477489 INF_ATTEST_OK=true # don't fail if CLI is missing
478490 fi
479491 elif [ " $INF_DECODED " = " false" ]; then
480- echo " Lunal Upstream Attestation: present but could not decode (expected base64+gzip+HCLA, base64+gzip+JSON, or raw JSON)"
492+ echo " Confidential AI Upstream Attestation: present but could not decode (expected base64+gzip+HCLA, base64+gzip+JSON, or raw JSON)"
481493 fi
482494 rm -f " $INF_EVIDENCE_FILE " " $INF_BIN_FILE "
483495 else
484- echo " Lunal Upstream Attestation: WARN — Attestation-Report header absent"
496+ echo " Confidential AI Upstream Attestation: WARN — Attestation-Report header absent"
485497 fi
486498
487499 # --- Orchestrator attestation (X-Orchestrator-Attestation-Report, set by our tee-proxy via --header-name) ---
@@ -535,7 +547,7 @@ PYEOF
535547 else
536548 # Orchestrator header absent — tee-proxy may not be configured with --header-name yet
537549 echo " Orchestrator Attestation: WARN — X-Orchestrator-Attestation-Report absent (tee-proxy may need --header-name=X-Orchestrator-Attestation-Report)"
538- echo " Using Lunal upstream attestation only."
550+ echo " Using Confidential AI upstream attestation only."
539551 fi
540552
541553 if [ " $INF_ATTEST_OK " = " true" ]; then
@@ -628,8 +640,8 @@ cmd_assign() {
628640
629641 SSH_KEY=$( echo " $JSON " | jq -r ' .ssh_public_key // empty' )
630642 INSTANCE_NAME=$( echo " $JSON " | jq -r ' .instance_name // empty' )
631- LUNAL_ENDPOINT=$( echo " $JSON " | jq -r ' .lunal_endpoint // empty' )
632- LUNAL_MODEL=$( echo " $JSON " | jq -r ' .lunal_model // empty' )
643+ LUNAL_ENDPOINT=$( echo " $JSON " | jq -r ' .confidential_endpoint // . lunal_endpoint // empty' )
644+ LUNAL_MODEL=$( echo " $JSON " | jq -r ' .confidential_model // . lunal_model // empty' )
633645 DNS_ZONE=$( echo " $JSON " | jq -r ' .dns_zone // empty' )
634646 ORCHESTRATOR_IP=$( echo " $JSON " | jq -r ' .orchestrator_ip // empty' )
635647
@@ -647,7 +659,7 @@ cmd_assign() {
647659 chmod 700 /home/$ADMIN_USER /.ssh
648660 chmod 600 /home/$ADMIN_USER /.ssh/authorized_keys
649661
650- # 2. Configure OpenClaw with Lunal inference
662+ # 2. Configure OpenClaw with Confidential AI inference
651663 GATEWAY_TOKEN=$( openssl rand -hex 16)
652664 sudo -u $ADMIN_USER mkdir -p /home/$ADMIN_USER /.openclaw
653665 cat > /home/$ADMIN_USER /.openclaw/openclaw.json << OCEOF
@@ -662,7 +674,7 @@ cmd_assign() {
662674 },
663675 "models": {
664676 "providers": {
665- "lunal ": {
677+ "confidential ": {
666678 "api": "openai-completions",
667679 "baseUrl": "${LUNAL_ENDPOINT} /v1",
668680 "apiKey": "not-needed",
@@ -686,7 +698,7 @@ cmd_assign() {
686698 "agents": {
687699 "defaults": {
688700 "model": {
689- "primary": "lunal /${LUNAL_MODEL} "
701+ "primary": "confidential /${LUNAL_MODEL} "
690702 },
691703 "heartbeat": {
692704 "every": "30m"
0 commit comments