Identity-Linked Token Protocol
Tokens that must respect real-world rules, such as who is allowed to hold them, have no way to carry that requirement. This attaches identity credentials so the rules travel with the token.
Summary
- Why
- Regulated tokens need to enforce who can hold or transfer them without forcing every participant to expose their full identity to prove it.
- What
- BRC-108 is a protocol that attaches identity certificate requirements to token transfers so ownership can be restricted by verified facts like accreditation or country while keeping the rest of a holder's identity private.
- How
- A token's genesis transaction encodes compliance rules and a hash of the issuer's certificate, and every transfer must include proof that sender and recipient certificates satisfy those rules, with only the required fields decrypted for the counterparty.
What this lets you do
- Require a valid identity certificate before a token can be held or transferred
- Restrict tokens to certificate types, countries, or accreditation status
- Reveal only the specific certificate fields a compliance rule needs
- Set per-certificate-level limits like max transfer amount and daily limit
- Attach a time-locked recovery path tied to an alternate identity certificate
Written by claude-sonnet-5 from the specification text. Where the two differ, the original is correct.
Reference for an AI
Everything an assistant needs to answer questions about BRC-108 accurately, including what it depends on.
The specification
Abstract
This proposal extends the Enhanced Mandala Token Protocol (BRC-107) with [object Object] integration based on BRC-52/53. It enables tokens to enforce real-world compliance requirements, KYC/AML regulations, and identity-based access controls while preserving privacy through selective field revelation. The protocol supports regulated security tokens, accredited investor requirements, geographic restrictions, and identity-based recovery mechanisms, all validated through SPV-friendly cryptographic proofs.
Motivation
Current token systems on BSV lack native integration with identity verification, making regulatory compliance difficult and limiting adoption for security tokens and regulated assets. While BRC-52/53 provides a robust identity certificate system, there's no standard for linking these certificates to token ownership and transfers.
This proposal addresses:
- Regulatory compliance for security tokens requiring KYC/AML
- Accredited investor verification for restricted offerings
- Geographic restrictions for regulatory jurisdictions
- Identity-based recovery for lost keys
- Privacy-preserving compliance through selective revelation
- Fraud prevention through identity linkage
Specification
Identity-Bound Token Types
We define three levels of identity requirements for tokens:
- Open Tokens: No identity requirements (backward compatible with BRC-92/BRC-107)
- Verified Tokens: Require valid BRC-52 certificate
- Restricted Tokens: Require specific certificate fields or types
Enhanced Genesis Output
The genesis transaction establishes identity requirements:
21 <assetId>
<issuerCertificateHash>
<complianceRules>
<identityCommitment>
OP_2DROP OP_2DROP OP_2DROP OP_DROP ...
Where:
issuerCertificateHash: SHA-256 hash of issuer's BRC-52 certificatecomplianceRules: Encoded rules for token transfersidentityCommitment:H(assetId || issuerCertificate || complianceRules || maxSupply)
Compliance Rules Structure
{
"version": 1,
"requireIdentity": true,
"allowedCertificateTypes": [
"8l5phhdm2Hi80s6QqFOLS0NwUzDzJhlUTWv2BezmstE="
],
"requiredFields": ["country", "accreditedStatus"],
"restrictions": {
"allowedCountries": ["US", "CA", "GB"],
"minCertificateLevel": "enhanced_kyc",
"maxAmountPerIdentity": 10000,
"cooldownPeriod": 86400
}
}
Identity-Linked Token Output
21 <assetId> <amount>
<recipientCertificateHash>
<identityCommitment>
OP_2DROP OP_2DROP OP_2DROP OP_DROP P2PKH
Where:
recipientCertificateHash: SHA-256 hash of recipient's BRC-52 certificateidentityCommitment:H(assetId || amount || certificateHash || prevTxid)
Identity-Aware Transfer Protocol
When transferring identity-linked tokens, the sender provides:
{
"transaction": "hex_encoded_transaction",
"tokenProofs": {
"inputs": [...],
"outputs": [...],
"conservationProof": {...}
},
"identityProofs": {
"sender": {
"certificate": {
"type": "8l5phhdm2Hi80s6QqFOLS0NwUzDzJhlUTWv2BezmstE=",
"subject": "0376d67c86b45be3c36c328c2aa5c5dd79c546d2...",
"serialNumber": "kUahacBHmYL2nkzemkatFg==",
"certifier": "035ce8cc44dbcf4c991d666d381d67263aed9123...",
"revocationOutpoint": "48645047cd66f7b48b24efb080ec7e27...1",
"signature": "3045022100c0686907...",
"keyring": {
"country": "encrypted_for_recipient",
"accreditedStatus": "encrypted_for_recipient"
}
},
"certificateProof": {
"merkleProof": "...",
"blockHeight": 850000
}
},
"recipient": {
"certificateHash": "sha256_hash_of_recipient_certificate",
"certificateType": "8l5phhdm2Hi80s6QqFOLS0NwUzDzJhlUTWv2BezmstE="
}
},
"complianceAttestation": {
"rulesVersion": 1,
"checksPassed": [
"country_allowed",
"accredited_investor",
"amount_within_limit"
],
"timestamp": 1234567890,
"attestorSignature": "..."
}
}
Verification Protocol
Recipients and overlays MUST verify:
1. Standard Token Checks (from BRC-106)
- Commitment verification
- Conservation check
- Merkle proof validation
2. Identity Checks
function verifyIdentityCompliance(transfer) {
// Verify sender's certificate
if (!verifyCertificate(transfer.identityProofs.sender.certificate)) {
return false;
}
// Check certificate not revoked
if (isSpent(transfer.identityProofs.sender.certificate.revocationOutpoint)) {
return false;
}
// Verify certificate matches output
senderCertHash = H(transfer.identityProofs.sender.certificate);
if (senderCertHash != transfer.transaction.inputs[0].certificateHash) {
return false;
}
// Decrypt and verify required fields
fields = decryptFields(transfer.identityProofs.sender.certificate.keyring);
if (!meetsComplianceRules(fields, token.complianceRules)) {
return false;
}
// Verify recipient certificate type
if (!token.complianceRules.allowedCertificateTypes.includes(
transfer.identityProofs.recipient.certificateType)) {
return false;
}
return true;
}
Selective Field Revelation
Certificate holders reveal only required fields:
- Determine Required Fields: Based on token's compliance rules
- Encrypt for Recipient: Using BRC-52/53 key derivation
- Include in Transfer: Add encrypted keys to certificate keyring
- Recipient Decrypts: Using their identity key
Example revealing only country for geographic restriction:
{
"certificate": {
"fields": {
"firstName": "encrypted_not_revealed",
"lastName": "encrypted_not_revealed",
"country": "encrypted_value",
"city": "encrypted_not_revealed"
},
"keyring": {
"country": "encrypted_revelation_key_for_recipient"
}
}
}
Identity-Based Recovery
Tokens can include recovery conditions:
21 <assetId> <amount>
<primaryCertificateHash>
<recoveryCommitment>
OP_IF
<recoveryDelay> OP_CHECKSEQUENCEVERIFY OP_DROP
<recoveryCertificateHash> OP_EQUAL
OP_ELSE
<primaryCertificateHash> OP_EQUAL
OP_ENDIF
Where:
recoveryCommitment:H(certificateType || recoveryFields || recoveryPubkey)recoveryDelay: Time lock before recovery (e.g., 30 days)
Certificate Levels and Permissions
{
"certificateLevels": {
"basic_kyc": {
"maxTransferAmount": 1000,
"dailyLimit": 5000,
"allowedOperations": ["transfer", "receive"]
},
"enhanced_kyc": {
"maxTransferAmount": 10000,
"dailyLimit": 50000,
"allowedOperations": ["transfer", "receive", "stake"]
},
"institutional": {
"maxTransferAmount": null,
"dailyLimit": null,
"allowedOperations": ["transfer", "receive", "stake", "mint", "burn"]
}
}
}
Use Cases
1. Security Token Offering (STO)
// Genesis specifies accredited investor requirement
complianceRules = {
requiredFields: ["accreditedStatus", "country"],
allowedCountries: ["US"],
restrictions: {
mustBeAccredited: true,
minInvestment: 10000
}
}
2. Geographic Restrictions
// Token only transferable within specific regions
complianceRules = {
requiredFields: ["country"],
allowedCountries: ["EU", "UK", "CH"],
restrictions: {
blockRestrictedCountries: ["US", "CN", "RU"]
}
}
3. Age-Restricted Assets
// Gaming tokens requiring age verification
complianceRules = {
requiredFields: ["ageRange"],
restrictions: {
minimumAge: 18,
requireAgeAttestation: true
}
}
4. Institutional Trading
// Different limits based on certificate type
if (certificate.type == "retail") {
maxDailyVolume = 10000;
} else if (certificate.type == "qualified") {
maxDailyVolume = 100000;
} else if (certificate.type == "institutional") {
maxDailyVolume = unlimited;
}
Privacy Considerations
Zero-Knowledge Proofs
For sensitive compliance checks, support ZK proofs:
- Prove age > 18 without revealing exact age
- Prove accredited status without revealing net worth
- Prove country membership without revealing specific country
Encrypted Field Storage
All certificate fields remain encrypted until revelation:
- Only revealed fields are decrypted
- Revelation is counterparty-specific
- No permanent plaintext exposure
Pseudonymous Compliance
Users can maintain pseudonymity while proving compliance:
- Certificate links to pubkey, not real name
- Only certifier knows real identity
- Selective revelation preserves privacy
Security Considerations
Certificate Validation
- Always verify certificate signatures
- Check revocation status via UTXO
- Validate certifier is trusted
- Ensure certificate hasn't expired
Replay Protection
- Include prevTxid in commitments
- Timestamp compliance attestations
- Use nonces for uniqueness
Key Compromise
- Certificate revocation via UTXO spending
- Recovery mechanisms for token access
- Time-locked recovery periods
Migration and Compatibility
Backward Compatibility
- Open tokens work without identity
- Existing BRC-92/106 tokens unaffected
- Optional identity for gradual adoption
Migration Path
- Phase 1: Deploy identity-aware wallets
- Phase 2: Certifiers issue BRC-52 certificates
- Phase 3: Token issuers adopt compliance rules
- Phase 4: Overlays enforce identity requirements
- Phase 5: Full ecosystem adoption
Implementation Examples
Creating Identity-Linked Token
async function createIdentityToken(params) {
// Get issuer's certificate
const issuerCert = await wallet.getCertificate();
// Define compliance rules
const rules = {
requireIdentity: true,
allowedCertificateTypes: [params.certificateTypeId],
requiredFields: params.requiredFields,
restrictions: params.restrictions
};
// Create genesis with identity binding
const genesis = {
assetId: generateAssetId(),
issuerCertificateHash: hash(issuerCert),
complianceRules: rules,
identityCommitment: hash(
assetId + issuerCert + rules + params.maxSupply
)
};
return createGenesisTransaction(genesis);
}
Transferring with Compliance
async function transferWithCompliance(amount, recipient) {
// Get certificates
const senderCert = await wallet.getCertificate();
const recipientCert = await requestCertificate(recipient);
// Check compliance
const compliance = await checkCompliance(
senderCert,
recipientCert,
token.complianceRules
);
if (!compliance.passed) {
throw new Error(`Compliance failed: ${compliance.reason}`);
}
// Reveal required fields
const keyring = await revealFields(
senderCert,
token.complianceRules.requiredFields,
recipient
);
// Create transfer
return {
transaction: createTokenTransfer(amount, recipient),
identityProofs: {
sender: {
certificate: senderCert,
keyring: keyring
},
recipient: {
certificateHash: hash(recipientCert)
}
},
complianceAttestation: compliance.attestation
};
}
Test Vectors
Identity Commitment
Input:
assetId: "abc...def:0"
certificateHash: "123...789"
amount: 100
prevTxid: "def...456"
Output:
commitment = SHA256(assetId || amount || certificateHash || prevTxid)
= "xyz...123"
Compliance Check
Certificate Fields:
country: "US"
accreditedStatus: "true"
Compliance Rules:
allowedCountries: ["US", "CA"]
mustBeAccredited: true
Result: PASS ✓
References
- BRC-52: Identity Certificates
- BRC-53: Certificate Creation and Revelation
- BRC-92: Mandala Token Protocol
- BRC-107: Enhanced Mandala Token Protocol
- BRC-43: Security Levels, Protocol IDs, Key IDs and Counterparties
- BRC-2: Data Encryption and Decryption
- BRC-3: Digital Signature Creation and Verification
Implementations
Reference implementations:
- TypeScript: Coming Soon
- Go: Coming Soon
- Python: Coming Soon