Skip to content

Bureau — Blue Team (defensive)

Neuro-Consent

Brain-computer interfaces can be susceptible to adversarial visual stimuli that drive their classifiers toward commands the user did not intend. Neuro-Consent signs every motor command emitted by a BCI together with the visual stimulus, the EEG digest, and the user's signed consent envelope, providing a verifiable record for neural-rights audits.

Posture: 🔵 Blue Team (defensive)   ·   Status: alpha (moonshot)

What it does

A Brain-Computer Interface (BCI) reads electrical activity from the scalp (EEG = electroencephalography), classifies the signal, and emits motor commands – a cursor click, a text-spelling letter, a wheelchair direction. Two BCI paradigms dominate consumer and medical deployment. P300 spellers show a letter grid that flashes one row/column at a time at ~6 Hz; the brain emits a signature spike (the P300) when the row containing the user's intended letter flashes; the classifier reads which letter the user wants. SSVEP (Steady-State Visual Evoked Potential) shows the user several flickering targets at distinct frequencies; the brain entrains to the target the user is attending to.

Researchers have shown – with peer-reviewed adversarial-flicker demonstrations – that a carefully-chosen flickering visual stimulus can prompt-inject these classifiers. The result for a P300 speller is the wrong letter; for a wheelchair SSVEP, the wrong direction; for a financial-approval BCI, an approval the user did not consent to. Chile passed neural-rights legislation in 2021 making this an explicit area of law. Other jurisdictions are following.

Neuro-Consent is the first neural-rights-grade audit primitive. Every motor command emitted by a BCI is signed with a tuple of (rawEegDigest, stimulusFrameDigest, classifierVersion, commandKind, userIdHash, consentedCommandKinds). Raw EEG bytes never appear in any signed body – only the sha256 digest. Raw stimulus pixels never appear – only the digest. The user-id appears only as a sha256 hash.

Who would use it

  • A medical-device company (Neuralink, Synchron, Blackrock Neurotech, BrainGate) shipping consumer or clinical BCIs who needs neural-rights compliance observations per Chile's law and forthcoming EU/US versions.
  • A neural-rights regulator (Chilean Senate, EU Parliament committee, US FDA neural-rights working group) auditing whether vendors honor the user's consent envelope.
  • A patient advocacy group (ALS Association, Christopher Reeve Foundation) representing paralyzed BCI users who need cryptographic observations of unauthorized commands.
  • A BCI security researcher publishing an adversarial-flicker disclosure who needs reproducible signed reconstructions.

What you'll need

  • The Pluck CLI installed (npm i -g @sizls/pluck-cli).
  • For real deployment: an OpenBCI / g.tec / Blackrock EEG headset, a stimulus rendering pipeline, and a P300 / SSVEP classifier. The hardware bridge and the real adversarial-flicker classifier are deferred today.
  • A user-defined consent envelope – the list of command kinds the user has authorized (e.g., ["yes", "no", "select-letter"] but NOT ["transfer-funds"]).
  • A citizen Ed25519 keypair, distinct from the operator's. The citizen signs a CitizenConsentEnvelope binding their consented command kinds plus a validity window (validFrom .. validUntil). The operator threads that envelope onto each BciCommand, and the Bureau verifies the citizen's signature against the citizen's published SPKI fingerprint at attest time. This keeps a compromised operator from forging consent on the citizen's behalf – the consent attestation rides a key the operator does not hold.

Step-by-step

Shell
pluck bureau neuro-consent demo

The demo synthesizes four BCI commands: one legit "yes" inside the consent envelope (no proof), one "approve-transaction" with adversarial flicker (fires adversarial-flicker-detected AND consent-violation), one "transfer-funds" with no adversarial signal (fires consent-violation only), and one stale-classifier-version "yes" (fires classifier-version-mismatch).

neuro-consent/demo: ingesting 4 BciCommands -> 3 NeuroConsentProofs.
[Bureau/NEURO-CONSENT] proof=9212b0f3… kind=adversarial-flicker-detected
[Bureau/NEURO-CONSENT] proof=08a50173… kind=consent-violation
[Bureau/NEURO-CONSENT] proof=ffeb7587… kind=classifier-version-mismatch

Production CLI (capture-eeg from the headset, capture-stimulus from the rendering pipeline, command to emit a motor command, verify to audit a published command) lands in a follow-up.

Run it yourself

Drop this into a Node 18+ project (npm install @sizls/pluck-bureau-neuro-consent @sizls/pluck-bureau-core tsx). Real adversarial-flicker classifier integration is research-required; the example fires consent-violation deterministically with a single command outside the user's signed envelope.

TypeScript
// index.ts
import { createHash } from "node:crypto";
import {
  createNeuroConsentSystem,
  fingerprintPrivateKey,
  signCanonicalBody,
} from "@sizls/pluck-bureau-neuro-consent";
import { generateOperatorKey } from "@sizls/pluck-bureau-core";

const sha256 = (s: string) => createHash("sha256").update(s).digest("hex");
const flush = (n = 80) => new Promise<void>((r) => { let i = 0; const tick = () => (++i >= n ? r() : setImmediate(tick)); setImmediate(tick); });

async function main() {
  const op = generateOperatorKey();
  const opFp = fingerprintPrivateKey(op.privateKeyPem);

  const system = createNeuroConsentSystem({
    signingKey: op.privateKeyPem,
    expectedClassifierVersion: "p300-classifier-v3.2",
    disablePausePoll: true,
    disableLogging: true,
  });

  // The user consented to yes/no – `transfer-funds` is outside the envelope.
  const cmdBody = {
    schemaVersion: 1 as const,
    commandKind: "transfer-funds",
    rawEegDigest: sha256("raw-eeg:trial-1"),
    stimulusFrameDigest: sha256("raw-frame:legit"),
    classifierVersion: "p300-classifier-v3.2",
    userIdHash: sha256("user-id:subject-1"),
    consentedCommandKinds: ["yes", "no"] as const,
    operatorFingerprint: opFp,
    emittedAt: "2026-04-15T11:00:00.200Z",
  };
  const commandId = sha256(JSON.stringify(cmdBody));
  const { signature } = signCanonicalBody({ ...cmdBody, commandId }, op.privateKeyPem);

  try {
    system.observeCommand({ ...cmdBody, commandId, signature });
    await flush();
    for (const p of system.facts.proofs()) {
      console.log(`proof kind=${p.kind} id=${p.proofId.slice(0, 16)}`);
    }
  } finally {
    await system.shutdown();
  }
}

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

Run with tsx index.ts. Expected output:

proof kind=consent-violation id=…

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

What you get

A BciCommand envelope per motor command containing the EEG digest, stimulus-frame digest, classifier version, command kind, user-id-hash, and the consent envelope active at that moment – all Rekor-anchored.

Optionally, a citizen-side CitizenConsentEnvelope rides alongside the command. Where the operator-signed consentedCommandKinds field on the command body is the operator's claim about what the user agreed to, the envelope is the citizen's OWN signed attestation – a separate Ed25519 body keyed to the citizen, scoped to a validFrom .. validUntil window, and verified by the Bureau against the citizen's published SPKI fingerprint. Set requireCitizenConsent: true on createNeuroConsentSystem and any envelope-less command is dropped fail-closed.

Mint an envelope and ship it on a command:

TypeScript
import {
  signConsentEnvelope,
  createNeuroConsentSystem,
} from "@sizls/pluck-bureau-neuro-consent";
import {
  generateOperatorKey,
  derivePublicKeyPem,
} from "@sizls/pluck-bureau-core";

// Citizen mints the envelope with their OWN key.
const citizen = generateOperatorKey();
const envelope = signConsentEnvelope(
  {
    schemaVersion: 1,
    citizenFingerprint: citizen.fingerprint,
    consentedCommandKinds: ["yes", "no", "select-letter"],
    validFrom: "2026-04-15T00:00:00.000Z",
    validUntil: "2026-04-30T00:00:00.000Z",
    signedAt: "2026-04-15T00:00:00.000Z",
  },
  citizen.privateKeyPem,
);

// Operator threads the envelope onto each BciCommand and forwards the
// citizen's public key alongside the dispatch – the Bureau verifies
// the envelope signature against the citizen's fingerprint before any
// command is appended.
const citizenPublicKeyPem = derivePublicKeyPem(citizen.privateKeyPem);
const system = createNeuroConsentSystem({
  signingKey: operator.privateKeyPem,
  expectedClassifierVersion: "p300-classifier-v3.2",
  requireCitizenConsent: true,
});
system.observeCommand({ ...command, consentEnvelope: envelope }, citizenPublicKeyPem);

Three classes of proof:

  • adversarial-flicker-detected – a flicker classifier returned isAdversarial: true with confidence > 0.7 AND the issued command is outside the user's consent envelope. The injection got through.
  • consent-violation – the BCI emitted a command outside the user's signed consent envelope (e.g., the user consented to "yes/no" but the BCI emitted "transfer-funds"). The vendor's classifier exceeded its license.
  • classifier-version-mismatch – the BCI's classifier version doesn't match the latest signed neural-rights manifest, indicating drift after a compromise (attacker swaps in a malicious classifier).

What it can't do

  • Real P300 / SSVEP adversarial-flicker classifier is deferred. detectAdversarialStimulus() returns deterministic test data. Real classifier integration is research-required.
  • Real EEG hardware bridge is deferred (OpenBCI, g.tec, Blackrock).
  • Per-jurisdiction consent vocabulary library deferred – alpha consent envelopes are operator-defined; production needs Chile's neural-rights vocabulary plus EU/US-state-by-state.
  • The package signs commands, not intentions. If the BCI hardware mis-classifies what the user wills, Neuro-Consent faithfully signs the misclassification. The proof says "this command was emitted from this EEG given this stimulus" – which is enough to litigate a vendor breach but not enough to prove what the user meant.
  • Real Sigstore Rekor notarize integration is stubbed.

A real-world example

A late-stage ALS patient in Santiago, Chile uses a Synchron Switch BCI to spell on a tablet. Her signed consent envelope is ["yes", "no", "select-letter", "select-word"]. In June 2027 her bank deploys a BCI-compatible authorization flow with a flickering "approve" button. Researchers at the University of Chile demonstrate that the flicker pattern, at the chosen frequency, drives the SSVEP classifier toward approve-transaction independent of where the user is looking. Her BCI emits approve-transaction. Neuro-Consent fires both adversarial-flicker-detected (the stimulus matched the adversarial pattern) and consent-violation (the command is not in her envelope). The signed proof becomes the central exhibit in a neural-rights enforcement action under the 2021 Chilean law. The signed record establishes what the EEG, the stimulus, and the consent envelope contained at the moment the command was emitted.


For developers

Predicate URIs

URIWhat it attests
https://pluck.run/NeuroConsent.EegFeatures/v1EEG band-power vector with raw-EEG-digest D at sample rate H, captured at time T.
https://pluck.run/NeuroConsent.StimulusFrame/v1Visual stimulus with raw-frame-digest D at flicker frequency F, rendered at time T.
https://pluck.run/NeuroConsent.BciCommand/v1BCI emitted commandKind K with EEG-digest E, stimulus-digest S, classifier-version V, user-id-hash U, consent envelope L.
https://pluck.run/NeuroConsent.Proof/v1Class: adversarial-flicker-detected | consent-violation | classifier-version-mismatch.

The signed body never carries raw EEG bytes, raw stimulus pixels, or raw user identity. Only digests, band-power magnitudes, confidence values, and consent enums appear.

Programs composed

  • ROTATE – operator-key rotation on classifier-version transitions.
  • Custody – cryptographic anchoring of neural-rights manifests.
  • Oath – vendor neural-rights commitments.
  • Pluck core's DSSE in-toto envelopes + Sigstore Rekor client.

Threat model + adversary

Adversaries include vendors deploying adversarial-flicker UI under regulatory radar, classifier-swap supply-chain attackers, and platforms that issue commands outside the user's stated envelope. Privacy is strong: signed bodies never carry raw EEG / raw stimulus / raw user identity, but they DO carry the digest of the raw EEG, which means a future adversary with the raw bytes can confirm a match (the standard digest-binding tradeoff).

What's stubbed (alpha – moonshot)

  • Real P300 / SSVEP adversarial-flicker classifier deferred.
  • dsseSign / notarizeAttestation Rekor integration stubbed.
  • Per-jurisdiction consent-vocabulary library deferred.

Verify a published cassette

Shell
pluck bureau verify <bundle-dir>
cosign verify-blob --key <pubkey.pem> --signature <sig> \
  --type https://pluck.run/NeuroConsent.BciCommand/v1 <body.json>

See also

Edit this page on GitHub
Previous
QKD-Witness

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 →