inspectable · not a cert
What the agent signs
MyColo does not certify hardware. We ask YOUR agent (or you) to sign a receipt on YOUR machine. The MyColo agent is the requester, not the signer.
Pin this page against mycolo-measure inspect on your machine. If the file hashes differ, do not sign.
Does
- Read GPU / VRAM / CPU / RAM / OS via collect (nvidia-smi or sysfs).
- Build a v0 bundle. Drop os_name from the hash. Drop signoffs from the hash.
- SHA-256 the canonical JSON → content_sha256.
- Ed25519-sign ONLY the utf-8 bytes of that hex digest.
- Append {public_key_hex, signature_hex, signer_kind, signer_label, statement=hardware-receipt-v0}.
- Keep the seed at ~/.config/mycolo/ed25519.seed (mode 0600). Never upload it.
Does not
- Open a network socket. sign / verify / keygen / collect have no HTTP.
- Read hostname, MAC, serial, username, or home path.
- Put os_name in the hardware fingerprint.
- Certify tok/s. signed ≠ measured.
- Run a model or download weights.
- Send the seed, the raw key, or the full desk dump anywhere.
The only bytes signed
utf-8 bytes of content_sha256 (64 hex chars). Not the JSON, not the GPU string, not a MyColo token.
Statement: hardware-receipt-v0. Key stays at ~/.config/mycolo/ed25519.seed.
Source pins
measure/receipt.py· sha2568ca9c44f4161a63c616912ce56ebce0475c31dc5910cb1056dc1a0c84c2e9387· 5158 bytesmeasure/collect.py· sha2560402bde2347f8c49d3cc66269087864b1d0699df3efbd5041c0f6c2d5e2de852· 3872 bytes
Import audit: clean — no HTTP / socket in the signer.
receipt.py
"""Ed25519 hardware receipts.
A sign-off means: this key attests it observed this readout and this document.
It is not UL, NIST, or NVIDIA confidential-compute attestation.
"""
from __future__ import annotations
import hashlib
import json
import os
from datetime import datetime, timezone
from pathlib import Path
from nacl.exceptions import BadSignatureError
from nacl.signing import SigningKey, VerifyKey
from schema.models import Bundle, HardwareReadout, SignOff, SignerKind
KEY_DIR = Path(os.environ.get("MYCOLO_KEY_DIR", Path.home() / ".config" / "mycolo"))
KEY_PATH = KEY_DIR / "ed25519.seed"
def _sha256(data: bytes) -> str:
return hashlib.sha256(data).hexdigest()
def hardware_fingerprint(hw: HardwareReadout) -> str:
blob = json.dumps(
hw.model_dump(mode="json", exclude={"os_name"}),
sort_keys=True,
separators=(",", ":"),
).encode()
return _sha256(blob)
def canonical_bundle(bundle: Bundle) -> bytes:
payload = bundle.model_dump(mode="json", exclude={"content_sha256", "signoffs"})
hw = payload.get("hardware")
if isinstance(hw, dict):
hw.pop("os_name", None)
return json.dumps(payload, sort_keys=True, separators=(",", ":")).encode()
def stamp(bundle: Bundle) -> Bundle:
bundle.hardware_fingerprint = hardware_fingerprint(bundle.hardware)
bundle.content_sha256 = _sha256(canonical_bundle(bundle))
return bundle
def keygen(path: Path = KEY_PATH) -> str:
path.parent.mkdir(parents=True, exist_ok=True)
if path.exists():
raise FileExistsError(f"key already exists: {path}")
sk = SigningKey.generate()
path.write_bytes(bytes(sk))
path.chmod(0o600)
return bytes(sk.verify_key).hex()
def load_signing_key(path: Path = KEY_PATH) -> SigningKey:
raw = path.read_bytes()
return SigningKey(raw)
def public_key_hex(path: Path = KEY_PATH) -> str:
return bytes(load_signing_key(path).verify_key).hex()
def sign_bundle(
bundle: Bundle,
*,
signer_kind: SignerKind,
signer_label: str | None,
path: Path = KEY_PATH,
) -> Bundle:
bundle = stamp(bundle)
sk = load_signing_key(path)
msg = (bundle.content_sha256 or "").encode()
sig = sk.sign(msg).signature
bundle.signoffs.append(
SignOff(
public_key_hex=bytes(sk.verify_key).hex(),
signature_hex=sig.hex(),
signed_at=datetime.now(timezone.utc),
signer_kind=signer_kind,
signer_label=signer_label,
)
)
return bundle
def verify_signoff(bundle: Bundle, signoff: SignOff) -> bool:
digest = bundle.content_sha256 or _sha256(canonical_bundle(bundle))
try:
vk = VerifyKey(bytes.fromhex(signoff.public_key_hex))
vk.verify(digest.encode(), bytes.fromhex(signoff.signature_hex))
return True
except (BadSignatureError, ValueError):
return False
def verify_bundle(bundle: Bundle) -> dict:
recomputed = _sha256(canonical_bundle(bundle))
hash_ok = bundle.content_sha256 == recomputed
expected_fp = hardware_fingerprint(bundle.hardware)
fp_ok = bundle.hardware_fingerprint == expected_fp
results = []
for s in bundle.signoffs:
ok = hash_ok and verify_signoff(bundle, s)
results.append(
{
"ok": ok,
"signer_kind": s.signer_kind.value,
"signer_label": s.signer_label,
"public_key_hex": s.public_key_hex,
"statement": s.statement,
}
)
any_ok = any(r["ok"] for r in results)
return {
"receipt_ok": bool(any_ok and fp_ok and hash_ok),
"fingerprint_ok": fp_ok,
"hash_ok": hash_ok,
"hardware_fingerprint": expected_fp,
"signoffs": results,
"disclaimer": "First-party hardware receipt. Not a laboratory or OEM certification.",
}
def render_receipt(bundle: Bundle, verification: dict | None = None) -> str:
v = verification or verify_bundle(bundle)
hw = bundle.hardware
lines = [
"MYCOLO HARDWARE RECEIPT v0",
"First-party attestation — not a lab / OEM certificate.",
"",
f"fingerprint: {v['hardware_fingerprint']}",
f"fingerprint_ok: {v['fingerprint_ok']}",
f"receipt_ok: {v['receipt_ok']}",
f"gpu_or_soc: {hw.gpu_or_soc}",
f"vram_or_unified_mib: {hw.vram_or_unified_mib}",
f"driver: {hw.driver}",
f"cpu: {hw.cpu}",
f"stack: {hw.stack.value}",
f"content_sha256: {bundle.content_sha256}",
]
if bundle.model:
lines.append(f"model: {bundle.model.build_id} {bundle.model.quant or ''}".rstrip())
if bundle.score:
lines.append(f"score_tok_s: {bundle.score.tok_per_s} (score trust={bundle.score.trust.value})")
lines.append("")
if not v["signoffs"]:
lines.append("signoffs: none")
for s in v["signoffs"]:
lines.append(
f"signoff: {s['signer_kind']}:{s['signer_label'] or '-'} "
f"ok={s['ok']} key={s['public_key_hex'][:16]}…"
)
lines.append("")
lines.append(v["disclaimer"])
return "\n".join(lines) + "\n"
collect.py
"""Hardware collection. No hostname, no username, no paths that doxx the box."""
from __future__ import annotations
import json
import platform
import shutil
import subprocess
from pathlib import Path
from schema.models import HardwareReadout, Stack
def _run(cmd: list[str]) -> str | None:
try:
r = subprocess.run(cmd, capture_output=True, text=True, timeout=8)
except (OSError, subprocess.TimeoutExpired):
return None
if r.returncode != 0:
return None
return r.stdout.strip() or None
def _mem_mib() -> int | None:
try:
data = Path("/proc/meminfo").read_text()
except OSError:
return None
for line in data.splitlines():
if line.startswith("MemTotal:"):
kb = int(line.split()[1])
return kb // 1024
return None
def _cpu() -> str | None:
try:
for line in Path("/proc/cpuinfo").read_text().splitlines():
if line.lower().startswith("model name"):
return line.split(":", 1)[1].strip()
except OSError:
return None
return platform.processor() or None
def _os_name() -> str | None:
# Distro / kernel family only. No hostname, no user.
try:
for line in Path("/etc/os-release").read_text().splitlines():
if line.startswith("PRETTY_NAME="):
return line.split("=", 1)[1].strip().strip('"')
except OSError:
pass
sysname = platform.system()
return sysname or None
def _nvlink_up() -> bool:
"""Family only. Do not parse PCI addresses or MACs."""
raw = _run(["nvidia-smi", "nvlink", "--status"])
if not raw:
return False
s = raw.lower()
return "gb/s" in s or "active" in s
def _cuda_interconnect(n: int) -> str | None:
if n < 2:
return None
return "nvlink" if _nvlink_up() else "pcie"
def collect_linux_nvidia() -> HardwareReadout | None:
if not shutil.which("nvidia-smi"):
return None
raw = _run(
[
"nvidia-smi",
"--query-gpu=name,memory.total,driver_version",
"--format=csv,noheader,nounits",
]
)
if not raw:
return None
lines = [ln.strip() for ln in raw.splitlines() if ln.strip()]
if not lines:
return None
parsed = []
for line in lines:
parts = [p.strip() for p in line.split(",")]
if len(parts) < 3:
continue
name, mem, driver = parts[0], parts[1], parts[2]
try:
mem_mib = int(float(mem))
except ValueError:
mem_mib = None
parsed.append((name, mem_mib, driver))
if not parsed:
return None
names = [p[0] for p in parsed]
n = len(parsed)
if n > 1 and len(set(names)) > 1:
name = "mixed: " + "+".join(sorted(set(names)))
elif n > 1:
name = f"{n}× {names[0]}"
else:
name = names[0]
mems = [p[1] for p in parsed if p[1] is not None]
mem_mib = sum(mems) if mems else None
driver = parsed[0][2]
return HardwareReadout(
stack=Stack.cuda,
gpu_or_soc=name,
vram_or_unified_mib=mem_mib,
driver=driver,
cpu=_cpu(),
system_ram_mib=_mem_mib(),
os_name=_os_name(),
interconnect=_cuda_interconnect(n),
)
def collect() -> HardwareReadout:
nvidia = collect_linux_nvidia()
if nvidia:
return nvidia
# Apple / other: honest unknown rather than inventing a Studio.
return HardwareReadout(
stack=Stack.unknown,
gpu_or_soc=platform.machine() or "unknown",
cpu=_cpu(),
system_ram_mib=_mem_mib(),
os_name=_os_name(),
notes="No NVIDIA readout. On macOS run this CLI there for MLX/unified stats.",
)
def to_pretty(readout: HardwareReadout) -> str:
return json.dumps(readout.model_dump(mode="json"), indent=2)
Don't trust the page. Pin it.
A security review is three hashes. If any differ, stop.
# 1. What this site claims curl -sS https://mycolo.ai/api/signoff | python3 -c "import sys,json; [print(s['path'], s['sha256']) for s in json.load(sys.stdin)['sources']]" # 2. What this site actually serves curl -sS https://mycolo.ai/src/measure/receipt.py | sha256sum curl -sS https://mycolo.ai/src/measure/collect.py | sha256sum # 3. What you have locally sha256sum measure/receipt.py measure/collect.py # or: mycolo-measure inspect --check https://mycolo.ai
Import audit must be ok. That is an AST check: those two files cannot import HTTP or sockets. It is not a formal proof. It is a pin you can re-run.