{"signed":true,"current":{"algorithm":"ed25519","key_fingerprint":"sha256:8eb4c98fd59e067ce8651f0edec06bcccc6d92b49b2ddd8161929ec3826a5412","public_key":"VgeY7esoNK5uSXdt0DRLdS0K74K3hneAD2Gx5T1vd8s=","public_key_pem":"-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAVgeY7esoNK5uSXdt0DRLdS0K74K3hneAD2Gx5T1vd8s=\n-----END PUBLIC KEY-----\n","first_day":"2026-09-24","last_day":"2026-10-11"},"keys":[{"algorithm":"ed25519","key_fingerprint":"sha256:8eb4c98fd59e067ce8651f0edec06bcccc6d92b49b2ddd8161929ec3826a5412","public_key":"VgeY7esoNK5uSXdt0DRLdS0K74K3hneAD2Gx5T1vd8s=","public_key_pem":"-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAVgeY7esoNK5uSXdt0DRLdS0K74K3hneAD2Gx5T1vd8s=\n-----END PUBLIC KEY-----\n","first_day":"2026-09-24","last_day":"2026-10-11"}],"message":"the ASCII string \"tensile-export-manifest/v1:\" followed by the lowercase hex sha256 of manifest.json as the tarball holds it, no newline; ed25519","how_to_verify":"sentinel-verify-export -pubkey \u003cthis key\u003e \u003cexport\u003e.tar.gz checks the sidecar, every member against the manifest, and the signature, offline. verify_command does the signature check with OpenSSL 3 alone.","verify_command":"N=tensile-\u003cvantage\u003e-\u003cday\u003e.tar.gz; curl -sO $API/v1/exports/$N -O $API/v1/exports/$N.sig; curl -s $API/v1/exports/pubkey \u003e tensile-exports.json; jq -r --arg fp \"$(jq -r .key_fingerprint $N.sig)\" '.keys[] | select(.key_fingerprint == $fp) | .public_key_pem' tensile-exports.json \u003e tensile-exports.pem; printf '%s' \"tensile-export-manifest/v1:$(tar -xzOf $N manifest.json | sha256sum | cut -c1-64)\" \u003e msg; jq -r .signature $N.sig | base64 -d \u003e sig.bin; openssl pkeyutl -verify -pubin -inkey tensile-exports.pem -rawin -in msg -sigfile sig.bin","note":"Fetch the key once and keep it: a key fetched from the same server as the export proves only that both came from that server. Every key that ever signed an export here stays listed with the days it signed. Exports built before signing was switched on have no signature."}
