#!/usr/bin/env python3 # SPDX-License-Identifier: Apache-2.0 # Copyright (c) 2026 FALCONS.AI. Licensed under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with the # License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations. # This file — the free verifier — is the open-source component of Model # Surgeon (T3-a, operator-ruled Apache-2.0, 2026-08-31). The product itself # is proprietary; see LICENSE-verifier and NOTICE in the package. """ FALCONS.AI Model Surgeon — FREE attestation verifier. Anyone can verify a Surgeon package without a subscription: python verify_attestation.py package.zip [--key HEXKEY-OR-STRING] Checks, in order: 1. the package carries a lineage.intoto.jsonl attestation; 2. every subject artifact's SHA-256 matches the signed digest; 3. the DSSE HMAC signature verifies under the given key (--key or FALCONSAI_HMAC_KEY; defaults to the public key). Exit codes: 0 VERIFIED · 1 TAMPERED/INCOMPLETE · 2 not a Surgeon package. Verification is free by design: signed creation is the paid act, universal verification is what makes the signature worth anything. """ VERIFIER_VERSION = "2" # D-4 (V6.98): chain-aware import argparse import base64 import hashlib import hmac import json import os import sys import zipfile # SEC-7: this script used to default to a shipped secret — which meant the # signing key travelled inside every exported package. Anyone holding a # package could mint forgeries that verified. No default now: the verifier # requires the key out of band, exactly like any other shared secret. DEFAULT_KEY = None def main(): ap = argparse.ArgumentParser() ap.add_argument("package") ap.add_argument("--key", default=os.environ.get("FALCONSAI_HMAC_KEY")) a = ap.parse_args() try: z = zipfile.ZipFile(a.package) except Exception as e: print(f"✖ cannot open {a.package}: {e}") sys.exit(2) names = z.namelist() # v6.51 container fix (UPSTREAM_NOTE): some Windows tools zip with # backslash separators — normalize member names so those packages # verify instead of reading "not a Surgeon package". canon = {n.replace("\\", "/"): n for n in names} names = list(canon) prefix = "" roots = {n.split("/", 1)[0] for n in names if n.strip("/")} if len(roots) == 1 and all("/" in n for n in names if n.strip("/")): prefix = next(iter(roots)) + "/" # Explorer-style re-zip: descend def _zread(nm): return z.read(canon.get(prefix + nm, prefix + nm)) try: att = json.loads(_zread("lineage.intoto.jsonl")) except KeyError: print("✖ no lineage.intoto.jsonl — not a Surgeon package " "(or the attestation was stripped).") sys.exit(2) payload = base64.b64decode(att.get("payload", "")) want = (att.get("signatures") or [{}])[0].get("sig", "") # SEC-1: asymmetric first — the package carries the publisher's PUBLIC # key, so verification needs no secret and forgery needs the private # key. Free verification, restored properly. env_missing = False sig_uncheckable = False sig_entry = (att.get("signatures") or [{}])[0] or {} scheme = sig_entry.get("scheme") or "hmac" if scheme == "ed25519" and sig_entry.get("publicKey"): try: from cryptography.hazmat.primitives.asymmetric.ed25519 import ( Ed25519PublicKey) Ed25519PublicKey.from_public_bytes( bytes.fromhex(sig_entry["publicKey"])).verify( bytes.fromhex(want), payload) have = want print(f"signature : ed25519 OK · publisher {sig_entry.get('keyid')}") print(" (pin this fingerprint to establish WHO " "signed it)") except ImportError: # A missing library is an ENVIRONMENT problem, not evidence of # tampering — say so, keep checking digests, verdict INCOMPLETE. have = None env_missing = True print("signature : cannot check — install the 'cryptography' " "package (pip install cryptography) to verify ed25519") except Exception as e: have = None print(f"signature : ed25519 INVALID ({e})") elif a.key: have = hmac.new(a.key.encode(), payload, hashlib.sha256).hexdigest() print("signature : legacy shared-key (hmac) — anyone with the " "key could have produced this package") else: have = None sig_uncheckable = True print("signature : legacy shared-key package; supply --key or " "FALCONSAI_HMAC_KEY to check it (digests still verified)") sig_ok = have is not None and hmac.compare_digest(want, have) stmt = json.loads(payload) print(f"verifier : {VERIFIER_VERSION}") pt = stmt.get("predicateType") if pt == "https://falcons.ai/model-surgeon/lineage/v1": # packages written before V7.13: the legacy id (same schema) print(f"attestation : https://surgeon.falcons.ai/lineage/v1 (predicate type; this package carries the legacy id {pt})") else: print(f"attestation : {pt}") print(f"tool : {(stmt.get('predicate') or {}).get('tool')}") all_ok = True for sub in stmt.get("subject", []): nm, digest = sub["name"], sub["digest"]["sha256"] try: actual = hashlib.sha256(_zread(nm)).hexdigest() ok = actual == digest except KeyError: actual, ok = "", False except Exception: # e.g. the archive's own CRC rejects the entry — the byte-flip # case. Corruption is tampering evidence, not a crash. actual, ok = "", False all_ok &= ok print(f" {'✔' if ok else '✖'} {nm}") if not ok: print(f" signed {digest}\n actual {actual}") print(f"signature : {'✔ valid under this key' if sig_ok else '✖ does NOT verify under this key'}") # D-4 (V6.98, VERIFIER 2): the lineage CHAIN. A prior attestation, when the # package carries one, is checked for payload integrity and — when it was # signed by THIS package's key — for signature. A prior that cannot be # verified here is reported AMBER; it never makes this package TAMPERED. chain = (stmt.get("predicate") or {}).get("chain") if chain: depth = chain.get("depth") pr = chain.get("prior") if not pr: print(f"chain : depth {depth} · no prior attestation reachable at load") else: try: p_env = pr.get("envelope") or {} p_payload = base64.b64decode(p_env.get("payload", "")) p_digest = hashlib.sha256(p_payload).hexdigest() p_sig = (p_env.get("signatures") or [{}])[0] intact = p_digest == pr.get("digest") same_key = bool(sig_entry.get("publicKey")) and p_sig.get("keyid") == sig_entry.get("keyid") p_ok = None if intact and same_key and p_sig.get("scheme") == "ed25519" and p_sig.get("sig"): try: from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey as _PK _PK.from_public_bytes(bytes.fromhex(sig_entry["publicKey"])).verify( bytes.fromhex(p_sig["sig"]), p_payload) p_ok = True except Exception: p_ok = False state = ("prior VERIFIED (same publisher key)" if p_ok else "prior INVALID under this key — AMBER" if p_ok is False else "prior intact · signed by another key — not verified here (AMBER)" if intact else "prior payload does not match its recorded digest — AMBER") print(f"chain : depth {depth} · {state} · prior keyid {str(p_sig.get('keyid') or '?')[:20]} · {len(pr.get('operations') or [])} earlier operation(s)") except Exception as e: print(f"chain : depth {depth} · prior present but unreadable ({e}) — AMBER") merges = (stmt.get("predicate") or {}).get("merges") or [] if merges: print(f"merges : {len(merges)} recorded " f"({', '.join(sorted({m.get('method','lerp') for m in merges}))})") verdict = "VERIFIED" if sig_ok and all_ok and stmt.get("subject") \ else "INCOMPLETE" if ((env_missing or sig_uncheckable) and all_ok) \ else "TAMPERED" if stmt.get("subject") else "INCOMPLETE" print(f"\nVERDICT: {verdict}") sys.exit(0 if verdict == "VERIFIED" else 1) if __name__ == "__main__": main()