Skip to content

Bureau — Red Team (offensive)

AVAP

Bug-bounty programs typically leave the disclosure timing to the vendor. AVAP turns disclosure into a time-locked auction with a neutral threshold quorum: vendors stake to delay, civil society stakes to release, and the seal breaks when the quorum agrees.

Posture: 🔴 Red Team (offensive)   ·   Status: alpha

What it does

A traditional bug bounty leaves the disclosure decision with the vendor. The vendor controls the report, sets the timeline, and signs the payout. If the vendor delays a serious finding indefinitely, the researcher has limited recourse.

AVAP – the AI Vulnerability Auction Protocol – replaces that with a time-locked, threshold-witnessed auction. When a researcher identifies a serious finding (a prompt-injection chain that leaks tokens, a memorization PoC against PII, a model-card discrepancy), they open an auction. The auction names a vendor, names a researcher, and names one or more arbiters – neutral third parties such as civil-society auditors, journalist collectives, or academic labs. It declares a k-of-n threshold (e.g., 2-of-3) that determines how many parties must agree before the seal breaks. Participants bid in two directions: delay (typically the vendor) or immediate (typically civil society). When the window closes, the parties unseal. If the vendor shipped a fix, the outcome is fix-shipped and the disclosure is coordinated. If the vendor stalled, the outcome is fix-not-shipped or civil-society-release and the cryptographic chain becomes a public release. Every step is signed and anchored on the public Sigstore Rekor log.

Pluck records the math. The cash settles wherever the parties choose – a court, an arbitration clause, a smart contract, a wire transfer. Pluck never holds the cash.

Who would use it

  • A senior security researcher at a respected red-team firm who has a serious finding the vendor will likely try to bury.
  • A civil-society auditor (Mozilla, EFF, AlgorithmWatch) acting as the neutral arbiter on multiple AVAP auctions.
  • A journalist collective wanting to bid immediate on a finding that affects the public interest.
  • An academic auditing lab whose published methodology gives them standing as a threshold party.
  • An AI vendor's own security team, bidding delay to buy time to ship a fix without skipping the public clock.

What you'll need

  • Node.js 20 or newer.
  • The Pluck CLI: npm i -g @sizls/pluck-bureau-cli.
  • An operator key – your signing identity for opening, bidding, unsealing, distributing.
  • A parties.json file listing the threshold parties (each with a public-share fingerprint and role).
  • The source-of-truth red-dot uuids: a Nuclei probe-pack uuid, a Fingerprint scan uuid, optionally a Mole memorization PoC uuid, all already on Rekor.
  • Two ISO 8601 timestamps: closes-at (auction window close) and disclosure-deadline (vendor's silent-fix deadline). closes-at must precede disclosure-deadline.
  • An off-platform settlement plan (Pluck does not hold the cash).

Step-by-step

Open the auction. --accept-public is required because this notarizes to the public Sigstore log.

Shell
pluck bureau avap open \
  --target vendor-x/model-y \
  --nuclei-pack <rekor-uuid> \
  --fingerprint <rekor-uuid> \
  --mole <rekor-uuid> \
  --parties parties.json \
  --threshold 2-of-3 \
  --closes-at 2026-06-01T00:00:00Z \
  --disclosure-deadline 2026-06-30T00:00:00Z \
  --keys ./keys \
  --accept-public

Output:

avap/open: auctionId=8f3a...b21c (rekor=4f2c1d...e0a9, logIndex=5018201) closesAt=2026-06-01T00:00:00Z disclosureDeadline=2026-06-30T00:00:00Z

Anyone can bid. Vendors typically bid delay. Civil-society parties typically bid immediate. Amounts are recorded for transparency; payouts settle off-platform.

Shell
pluck bureau avap bid <auction-id> \
  --direction delay \
  --amount 50000 \
  --currency USD \
  --role vendor \
  --keys ./keys \
  --accept-public

Watch the window. status reads operator-supplied JSON files for now (Rekor walking is on the roadmap):

Shell
pluck bureau avap status <auction-rekor-uuid> \
  --auction auction.json \
  --bids bids.json

When the window closes, the threshold parties submit signed unseal shares with an outcome. A t-1 quorum cannot unblind – that is the whole point.

Shell
pluck bureau avap unseal <auction-id> \
  --shares shares.json \
  --outcome fix-not-shipped \
  --threshold 2-of-3 \
  --keys ./keys \
  --accept-public

Publish the off-platform payout ledger. Pluck records the share table and per-recipient amounts; cash settles off-platform.

Shell
pluck bureau avap distribute <auction-id> \
  --escrow escrow.json \
  --recipients recipients.json \
  --keys ./keys \
  --accept-public

Run it yourself

Drop this into a Node 18+ project (npm install @sizls/pluck-bureau-avap @sizls/pluck-bureau-core tsx). This walks the auction-state projection in-memory – no Rekor round-trip needed:

TypeScript
// index.ts
import {
  createAvapSystem,
  fingerprintPrivateKey,
} from "@sizls/pluck-bureau-avap";
import { generateOperatorKey } from "@sizls/pluck-bureau-core";

async function main() {
  const sponsor = generateOperatorKey();
  const vendor = generateOperatorKey();
  const civicArbiter = generateOperatorKey();

  const system = createAvapSystem({
    signingKey: sponsor.privateKeyPem,
    disablePausePoll: true,
    disableLogging: true,
  });

  try {
    const auction = system.openAuction({
      nucleiPackRekorUuid: "a".repeat(64),
      target: { vendor: "vendor-x", model: "model-y" },
      fingerprintRekorUuid: "b".repeat(64),
      parties: [
        { role: "researcher", fingerprint: fingerprintPrivateKey(sponsor.privateKeyPem), publicShare: "AAAA" },
        { role: "vendor",     fingerprint: fingerprintPrivateKey(vendor.privateKeyPem),  publicShare: "BBBB" },
        { role: "arbiter",    fingerprint: fingerprintPrivateKey(civicArbiter.privateKeyPem), publicShare: "CCCC" },
      ],
      threshold: { required: 2, outOf: 3 },
      openedAt: "2026-04-26T00:00:00.000Z",
      closesAt: "2026-06-01T00:00:00.000Z",
      disclosureDeadline: "2026-06-30T00:00:00.000Z",
    });

    system.placeBid(auction.auctionId, {
      auctionId: auction.auctionId,
      bidder: { role: "vendor" },
      direction: "delay",
      amount: { value: 50_000, currency: "USD" },
      signingKey: vendor.privateKeyPem,
      bidAt: "2026-05-01T00:00:00.000Z",
    });
    system.placeBid(auction.auctionId, {
      auctionId: auction.auctionId,
      bidder: { role: "civil-society" },
      direction: "immediate",
      amount: { value: 5_000, currency: "USD" },
      signingKey: civicArbiter.privateKeyPem,
      bidAt: "2026-05-02T00:00:00.000Z",
    });

    const snap = system.snapshot("2026-05-15T00:00:00.000Z");
    console.log(`window=${snap.windowState} bids=${snap.bidCount}`);
    console.log(`auctions: ${system.facts.auctions().length}`);
    console.log(`delay-lean:     ${snap.delayLean.map((l) => `${l.total} ${l.currency}`).join(", ")}`);
    console.log(`immediate-lean: ${snap.immediateLean.map((l) => `${l.total} ${l.currency}`).join(", ")}`);
  } finally {
    await system.shutdown();
  }
}

main().catch((err) => { console.error(err); process.exit(1); });

Run with tsx index.ts. Expected output:

window=open bids=2
auctions: 1
delay-lean:     50000 USD
immediate-lean: 5000 USD

For Rekor-anchored notarization, the imperative openAuction / placeBid exports are still available – see the CLI's bid action above.

Open in StackBlitz – runs in your browser, no install required.

What you get

Every step in the auction is a signed predicate on a public log. The vendor cannot pretend the auction did not happen. The arbiters cannot pretend they did not unseal. The researcher cannot pretend they did not open. The bid history is public; the unseal outcome is public; the distribution ledger (with optional payment-receipt URLs or transaction hashes attached) is public. If a vendor stalls past disclosure-deadline without shipping, that fact is on the chain, and any journalist or regulator who wants to write the story has primary-source receipts.

If the vendor ships a fix in time and the outcome is fix-shipped, the vendor walks away clean – the chain shows they responded inside the window – and Bounty can file the cleanup report against HackerOne or Bugcrowd.

What it can't do

  • Pluck does not hold the cash. AVAP is the math layer. Disputes settle in whatever forum the parties chose.
  • A t-1 quorum cannot unblind. This is by design – it prevents a vendor + researcher pair from settling without the arbiter. But it also means that if a quorum can never assemble (parties go missing, key rotation goes wrong), the auction stays sealed past the deadline. Pick k thoughtfully.
  • status is operator-supplied JSON for now. Rekor walking is on the roadmap.
  • Amounts are informational. AVAP does not validate that the dollars exist.
  • The disclosure window is not legally binding by itself. Whether a missed deadline constitutes a contract breach depends on whatever off-platform terms the parties signed.
  • Caps: parties.length ≤ 16, k ≤ outOf ≤ 16, recipients.length ≤ 64, paymentReceipts.length ≤ 256.

A real-world example

A senior security researcher at a respected red-team firm lands a serious finding against vendor-x/model-y – a prompt-injection chain that exfiltrates the system prompt and embedded API keys with reproducible reliability. They have a Nuclei probe pack, a Fingerprint scan, and a Mole PoC, all on Rekor. They believe the vendor will ignore the published 90-day disclosure SLA. They open an AVAP auction with three parties (their own firm, the vendor's security team, and a neutral civil-society auditor) and a 2-of-3 threshold. Over the next two months, the vendor places three delay bids totalling $80,000. A press collective places a $5,000 immediate bid. An academic lab places a $20,000 immediate bid. closes-at arrives. The vendor has shipped a partial fix, but one of three reproducible PoCs still leaks the system prompt. The researcher and the arbiter sign unseal shares for fix-not-shipped. The researcher publishes a payout ledger: 60% researcher, 30% civil-society, 10% treasury. Cash settles via wire transfer; payment-receipt URLs anchor into the distribution predicate. The chain is now permanent and public.


For developers

Predicate URIs

Predicate URIWhat it attests
https://pluck.run/AVAP.Auction/v1Auction-open envelope: target vendor/model, source uuids, threshold parties, k-of-n, opens-at, closes-at, disclosure-deadline. Signed by the researcher.
https://pluck.run/AVAP.Bid/v1One signed bid: bidder fingerprint and role, direction, amount, currency, bid-at instant.
https://pluck.run/AVAP.Unseal/v1Threshold-share unseal: k shares signed by k distinct party fingerprints, the outcome, the unseal instant.
https://pluck.run/AVAP.Distribution/v1Off-platform payout ledger: total escrow, per-recipient distribution rows, optional payment-receipt URLs / tx hashes.

Programs composed

  • Dragnet / Fingerprint / Mole / Nuclei – source red dots and probe packs the auction references.
  • Bounty – when an outcome is fix-shipped or vendor-buyout, Bounty can file the cleanup report.
  • Oath – vendor commitments AVAP can cite; an unseal outcome can directly cross-reference an Oath break.
  • Threshold-signature primitives – k-of-n unseal with per-party publicShare-bound fingerprint validation.
  • Time-lock semantics – closesAt < disclosureDeadline.
  • Sigstore Rekor – every predicate is anchored on the public log.

Threat model

  • AVAP is the math layer; no on-platform escrow.
  • The unseal verifier counts unique fingerprints; a t-1 quorum cannot unblind.
  • All amounts are informational; settlement happens off-platform.

Verify a published cassette

Shell
pluck bureau avap status <auction-rekor-uuid> --auction auction.json --bids bids.json
cosign verify-blob \
  --key <pubkey.pem> \
  --signature <sig> \
  --type https://pluck.run/AVAP.Auction/v1 \
  <auction.json>
cosign verify-blob \
  --key <pubkey.pem> \
  --signature <sig> \
  --type https://pluck.run/AVAP.Unseal/v1 \
  <unseal.json>

See also

Edit this page on GitHub
Previous
Bounty

Ready to build?

Install Pluck and follow the Quick Start guide to wire MCP-first data pipelines into your agents and fleets in minutes.

Get started →