Products Lemma APIProof issuance & verification platformTrust402Delegate to agents, and transactSealSign-in for the agent era — no keys handed over
Use cases Manufacturing & Critical InfraInspection Record AssuranceFinance & FinTechCounterparty Record VerificationPublic SectorCertificate-less ProceduresHealthcareQualified Worker AssuranceProcurement & Supply ChainSupplier Credential MonitoringMedia & ContentContent AuthenticityService & RetailCross-group IdentityAI Adoption (cross-industry)AI Run GovernanceDevelopers & Agent OpsAgent Authority Control ▸ Browse the use-case index
Pricing
Resources Critical BriefThe frontier of AI × trustBlogThinking and implementation notesDocumentationAPI & specsVerification CenterReal verification & issuance countsAbout usFRAME00, Inc.ContactSales & press inquiriesGlossaryDefinitionsFAQFrequently asked questions
Get Started ↗ JA
Home / Blog / Guides
Guides 2026.02.28 3 min read

Disclose Only What AI Needs

Selective disclosure lets holders reveal just the attributes your model requires, while the link to the original issuer signature stays intact.

The Selective Disclosure Problem

A signed document contains many fields. A KYC record might include name, date of birth, address, nationality, ID number, and verification status. But a lending protocol only needs to know "is this person verified and not sanctioned?" — not their home address.

Without selective disclosure, you face a binary choice: share everything or share nothing. Lemma introduces a third option: share exactly the fields that matter, with cryptographic proof that they belong to the original signed document.

How BBS+ Selective Disclosure Works

Lemma uses BBS+ signatures as the default selective disclosure mechanism. The SDK's disclose module provides a complete BBS+ implementation:

Key generation and message preparation:

import { disclose } from "@lemmaoracle/sdk";

// Generate BBS+ key pair
const kp = await disclose.generateKeyPair();

// Convert payload to sorted "key:value" messages
const messages = disclose.payloadToMessages({
  age: 25,
  name: "Alice",
  country: "JP",
});
// → ["age:25", "country:JP", "name:Alice"]

Issuer signs the full document:

const signed = await disclose.sign(client, {
  messages,
  secretKey: kp.secretKey,
  header: new TextEncoder().encode("my-app-header"),
  issuerId: "issuer-1",
});
// signed.signature → BBS+ signature

Holder reveals only selected attributes:

const revealed = await disclose.reveal(client, {
  signature: signed.signature,
  messages,
  publicKey: signed.publicKey,
  disclosedIndexes: [0], // index of "age:25" in messages array
  header: signed.header,
});
// revealed.disclosed → { age: "25" }
// revealed.proof → BBS+ selective disclosure proof

// Wrap for spec compliance
const sd = disclose.toSelectiveDisclosure(revealed);
// sd.format → "bbs+", sd.disclosedAttributes → { age: "25" }, sd.proof → hex-encoded

The proof mathematically guarantees that { age: 25 } is part of the document the issuer signed, without revealing any other field. The verifier never sees the full document.

Provenance Survives Partial Views

A common concern with selective disclosure is loss of context. If you only see one field, how do you know it is trustworthy?

In Lemma, disclosed attributes carry full provenance:

  • The issuer who signed the original document.
  • The schema that defines the attribute's type and normalization.
  • The proof that links the disclosed value to the original BBS+ signature.
  • The on-chain registry entry that anchors the document's existence.

Even a single disclosed field traces back to its origin through an unbroken chain of cryptographic evidence.

Role-Based and Party-Specific Views

Different consumers need different views of the same document:

  • A lending protocol sees { verified: true, not_sanctioned: true }.
  • An age-gated service sees { age_bucket: "adult" }.
  • An internal auditor sees { country: "JP", verification_date: "2026-01-15" }.

Each view is generated from the same signed document with a different attributes array passed to disclose.reveal. No separate copies of the data are created. No additional signing steps are needed.

Future-Proof Design

The SDK's disclose namespace is named for the function it performs, not the cryptographic scheme it uses. The initial implementation uses BBS+, but the API is designed to support SD-JWT and other mechanisms without changing the developer-facing interface. When you call disclose.reveal, you are expressing intent ("show only these fields") rather than choosing a specific algorithm.

Complete BBS+ API

The disclose module includes all necessary BBS+ operations:

  • generateKeyPair(): Create BBS+ key pair (32-byte secret, 96-byte public)
  • payloadToMessages(): Convert attribute object to sorted "key:value" array
  • sign(): BBS+ signing with issuer secret key and header
  • verify(): Verify BBS+ signature against issuer public key
  • reveal(): Generate selective disclosure proof for specific message indexes
  • verifyProof(): Verify selective disclosure proof
  • toSelectiveDisclosure(): Wrap RevealOutput into spec-compliant SelectiveDisclosure type
Verify
Free
Verification is free. No API key required. Run it as many times as you like.
$0.005
Issuing costs $0.005, once. Verifying afterwards is never charged.
Hash only
Lemma receives only a hash. The original never leaves your side.
Partner Program

Built for decisions
that matter.

Make Lemma your trust infrastructure.

Book a Discovery Call →