No shady code in this release.
shadybin rebuilds a release from its source and checks it is exactly what was published. Claude then reviews the code that goes into it. The verdict is signed in a public registry, and shows on the project's README as a badge.
Three checks, no people
Every release goes through the same three steps. The verdict follows from them by a fixed rule, and anyone can rerun the rule from the registry.
Rebuild
The release is rebuilt from its git tag, on the same kinds of runners the vendor uses. Every file must come out the same as the published one, so the source that gets reviewed is the source that was shipped.
Review
Claude reads all of the vendor's own code. For third-party code it reviews every new version's diff, and the parts of new dependencies a supply-chain attack would use. Packages are checked against their repositories for xz-style extra files. Read the prompt.
Sign
The verdict, certified or rejected, is signed and committed to a public registry. The badge always names the project's latest release, so a release nobody certified can't hide behind an old green one.
The badge
It names the release users are getting now, whatever shadybin made of it.
| Rebuilt, reviewed, nothing shady | v1.2.0 not shady |
| Rebuilt, but failed review | v1.2.0 shady |
| Released under a day ago, not yet signed | v1.2.0 pending |
| Never certified | v1.2.0 not certified |
The vendor pays
Certification runs in the vendor's own release workflow, on its GitHub Actions minutes and its Claude API key. shadybin runs only the registry.
Reviews of third-party code are cached and signed, so a popular dependency is reviewed once and the answer is shared with everyone. Each later release costs only its own changes, usually cents.
Updaters that only install certified releases
An updater that checks the registry before installing only ever updates to certified releases. There are small SDKs for Go, Rust, Zig, Python and TypeScript (and JavaScript). Each has shadybin's key built in and passes the same conformance tests. SDKs and CLI on GitHub
import "github.com/shadybin/shadybin/verify"
c := verify.Checker{} // trusts shadybin's own key
sum := sha256.Sum256(archive)
err := c.Check(ctx, "github.com/acme/tool", tag, "tool_Linux_x86_64.tar.gz", sum)
switch {
case err == nil:
// certified: install it
case errors.Is(err, verify.ErrPending):
// not certified yet: wait, and ask again
default:
// not certified: don't install
}
use shadybin_verify::{
verify, default_keys, statement_url, signature_url, DEFAULT_REGISTRY, Error,
};
// Fetch with the HTTP client you already have; a 404 means not certified yet.
let statement = fetch(&statement_url(DEFAULT_REGISTRY, repo, tag))?;
let signature = fetch(&signature_url(DEFAULT_REGISTRY, repo, tag))?;
let (keys, file) = (default_keys(), "tool_Linux_x86_64.tar.gz");
match verify(&statement, &signature, &keys, repo, tag, file, &digest) {
Ok(()) => install(),
Err(Error::Rejected) => {} // reviewed and refused: never install it
Err(_) => {} // not certified: don't install
}
const shadybin = @import("shadybin");
// statement and signature: the bytes at shadybin.statementUrl and signatureUrl.
// A 404 means not certified yet.
const keys = shadybin.defaultKeys();
const file = "tool-x86_64-linux";
shadybin.verify(statement, signature, &keys, repo, tag, file, digest) catch |err| switch (err) {
error.Rejected => return, // reviewed and refused: never install it
else => return, // not certified: don't install
};
try install();
import hashlib
import shadybin_verify as sb
# Fetch with the HTTP client you already have; a 404 means not certified yet.
statement = fetch(sb.statement_url(sb.DEFAULT_REGISTRY, repo, tag))
signature = fetch(sb.signature_url(sb.DEFAULT_REGISTRY, repo, tag))
try:
sb.verify(statement, signature, sb.default_keys(), repo, tag,
"tool_Linux_x86_64.tar.gz", hashlib.sha256(archive).digest())
install()
except sb.Rejected:
pass # reviewed and refused: never install it
except sb.Error:
pass # not certified: don't install
import {
verify, defaultKeys, statementUrl, signatureUrl, DEFAULT_REGISTRY, Rejected,
} from "@shadybin/verify";
// Fetch with the client you already have; a 404 means not certified yet.
const statement = await fetchBytes(statementUrl(DEFAULT_REGISTRY, repo, tag));
const signature = await fetchBytes(signatureUrl(DEFAULT_REGISTRY, repo, tag));
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", archive));
try {
await verify(statement, signature, defaultKeys(), repo, tag,
"tool_Linux_x86_64.tar.gz", digest);
install();
} catch (e) {
if (e instanceof Rejected) { /* reviewed and refused: never install it */ }
else { /* not certified: don't install */ }
}