Wallet Credentials
Current status
Sigma publishes its certifier identity and certificate catalog today. The public readiness response observed on September 5, 2026 reports issuance as disabled. Production revocation and wallet interoperability must be checked through the supported release process; the public endpoint does not reveal provisioning details.
Issuance is not live yet
GET https://auth.sigmaidentity.com/api/certificates/readiness currently returns
503 with {"service":"sigma-certifier","status":"disabled"}. The examples below document
the shipped contract, but a production acquireCertificate request cannot complete until Sigma
announces that issuance is enabled.
Sigma no longer implements the older custom two-request BRC-53 flow. There is no
/api/certificates/initialRequest endpoint, no caller-provided validationKey, and no
cookie-authenticated certificate subject. The current contract uses:
- BRC-52 for the signed certificate, encrypted fields, selective revelation, and revocation outpoint.
- BRC-100 for wallet acquisition, storage, listing, proof, and relinquishment.
- BRC-103 for mutual authentication between the subject wallet and Sigma.
- BRC-104 to carry that authenticated exchange over HTTPS.
- BRC-68 to publish Sigma's certifier identity at a familiar domain.
- BRC-116 for application permissions at the user's wallet.
Trust Sigma in a wallet
Sigma's canonical BRC-68 trust document is:
https://sigmaidentity.com/manifest.jsonIts metanet.trust.publicKey is the public identity used by Sigma for BRC-52 signing and
BRC-103/104 service authentication. A wallet can load the HTTPS manifest from the known domain,
show the name, note, icon, and public key, and let the user decide whether to add Sigma as a trusted
certifier.
Trust is not automatic. BRC-68 publishes identity details; it does not define a 1-to-10 score. BSV Desktop lets the user assign and store that score locally. Sigma cannot assign its own score or turn a published manifest into user consent. Before a wallet accepts a certificate, it should also confirm that all three identities match:
- the public key the user trusted from the BRC-68 manifest;
- Sigma's BRC-103 identity authenticated in the BRC-104 response; and
- the
certifierthat signed the BRC-52 certificate.
The legacy babbage.trust entry in Sigma's manifest is an identical migration copy. New software
should read the canonical metanet.trust entry.
Standard BRC-100 lifecycle
Applications talk to the user's wallet. They do not construct Sigma's encrypted issuance request or authentication headers themselves.
For example, an application can connect to the user's available BRC-100 wallet with the SDK client:
import { WalletClient } from '@bsv/sdk';
const wallet = new WalletClient('auto', 'example.com');The sigmaCertifierPublicKey used below must come from the current
metanet.trust.publicKey that the wallet fetched from Sigma's BRC-68 manifest, displayed, and the
user accepted. Do not hardcode a copied key; a changed manifest must be reviewed and accepted again.
1. Acquire
After the user has qualifying evidence in Sigma and has bound the subject wallet to the intended Sigma profile, request issuance through the wallet:
const certificate = await wallet.acquireCertificate(
{
acquisitionProtocol: 'issuance',
certifier: sigmaCertifierPublicKey,
certifierUrl: 'https://auth.sigmaidentity.com/api/certificates',
type: 'exOl3KM0dIJ04EW5pZgbZmPag6MdJXd3/a1enmUU/BA=',
fields: { email: 'alice@example.com' },
}
);The wallet encrypts each field, retains the master keyring, mutually authenticates with Sigma, and
sends the request to /api/certificates/signCertificate. Sigma takes the certificate subject only
from the verified BRC-103 session, decrypts the claims only for request-scoped validation, compares
them with current authoritative evidence, and returns a signed BRC-52 core certificate. Sigma does
not receive the user's private keys and does not return or retain the wallet's master keyring.
2. List
Find the user's locally held certificates by the exact trusted certifier and type:
const result = await wallet.listCertificates(
{
certifiers: [sigmaCertifierPublicKey],
types: ['exOl3KM0dIJ04EW5pZgbZmPag6MdJXd3/a1enmUU/BA='],
}
);Listing is a wallet operation. It does not make the certificate public and should not require an application to send the wallet's private certificate store to Sigma.
3. Prove selected fields
Reveal only the fields needed by one named verifier:
const proof = await wallet.proveCertificate(
{
certificate,
fieldsToReveal: ['email'],
verifier: verifierPublicKey,
}
);The wallet returns keyringForVerifier only for email. Other encrypted fields remain encrypted.
The verifier must verify Sigma's BRC-52 signature, decrypt only fields present in that verifier
keyring, trust the certifier independently, and perform a fresh revocation check before relying on
the result.
4. Relinquish locally
Remove a certificate from the user's wallet:
await wallet.relinquishCertificate(
{
type: certificate.type,
certifier: certificate.certifier,
serialNumber: certificate.serialNumber,
}
);Relinquishment is local deletion. It does not revoke the certificate, spend its revocation outpoint, or erase copies already shared with verifiers.
Wallet permission expectations
BRC-116 keeps each application request inside the wallet's permission boundary:
| Operation | Permission scope | What approval does not grant |
|---|---|---|
| Acquire | Originator and [1, "certificate acquisition <type>"] | Trust in Sigma, later disclosure, or public discovery |
| List | Originator and the single [1, "certificate list"] protocol permission | Acquisition, proof, relinquishment, or public discovery |
| Prove | Originator, exact certificate type, verifier public key, and field set | Any unrevealed field or proof to another verifier |
| Relinquish | Originator and [1, "certificate relinquishment <type>"] | Certificate revocation |
For acquisition and relinquishment, <type> is replaced by the exact Base64 certificate type.
Listing uses one originator-scoped [1, "certificate list"] protocol permission; it is not narrowed
to the types in a particular query. Disclosure uses a certificate-access check scoped to the exact
certificate type, verifier, and fields.
A wallet's local policy can allow a category without prompting. Otherwise it can apply an existing grant, ask the user, or deny the operation. Defaults vary by wallet and version; test the actual wallet policy instead of assuming a prompt is always shown. A denied acquisition must not store a certificate, and a denied proof must not reveal a field key.
Application permission and certifier trust answer different questions: permission asks whether an application may use a wallet capability; trust asks how much the user relies on Sigma's attestations.
Certificate catalog
The public catalog is served from
GET https://auth.sigmaidentity.com/api/certificates/types. Each entry includes
schemaVersion, displayName, description, field friendly names, documentationUrl, and
iconUrl. Type IDs and field names are immutable interoperability contracts. A new field or a
changed meaning requires a new type ID.
Browse human-readable landing pages at /certificates.
Catalog presence does not mean that production issuance is enabled or that a particular account is eligible. The wallet must use the exact Base64 type ID and exact plaintext field names shown below. The wallet encrypts the values; Sigma validates and signs the resulting BRC-52 certificate.
| Catalog key | Owner | Type ID | Fields | Landing page |
|---|---|---|---|---|
emailCert | Ecosystem | exOl3KM0dIJ04EW5pZgbZmPag6MdJXd3/a1enmUU/BA= | email | /certificates/email |
xCert | Ecosystem | vdDWvftf1H+5+ZprUw123kjHlywH+v20aPQTuXgMpNc= | userName, profilePhoto | /certificates/x |
discordCert | Ecosystem | 2TgqRC35B1zehGmB21xveZNc7i5iqHc0uxMb+1NMPW4= | userName, profilePhoto | /certificates/discord |
googleCert | Ecosystem | Kz3dpnvTRO+LzCF+X4zI1GQqRhVmgLGPWZQqG+vhVig= | email, name, profilePhoto | /certificates/google |
phoneCert | Ecosystem | mffUklUzxbHr65xLohn0hRL0Tq2GjW1GYF/OPfzqJ6A= | phoneNumber | /certificates/phone |
handleCert | Standard | XgCFdUfxEcI+3xtDjsIuSAjMl5EwzCUjsQc45ds1lC8= | domain, handle | /certificates/handle |
githubCert | Sigma | Wwu6i26Za++x25wQ1dbiMIsFMLSZdnmOQ8FlmFp61tc= | accountId, userName, profileUrl, profilePhoto, verifiedAt | /certificates/github |
appleCert | Sigma | YPPryWSjUukPRshIcWlyiMsPvnLXhGnrv7tXoprsWZQ= | accountId, verifiedAt | /certificates/apple |
bapWalletBinding | Sigma | ASzP6HaCWvCoYFTo5ggIvFbddIC4DPZN7IcK0VTwj00= | bapId, verifiedAt | /certificates/bap-wallet-binding |
providerAssurance | Sigma | mozxni6eTrXmAnKDQrtQW6OabMdCQ/2cWXPHa5NfGKE= | provider, accountId, assuranceLevel, verifiedAt, expiresAt | /certificates/provider-assurance |
organizationMembership | Sigma | qcMzD0ddeA4BYEHYZAKmyy5Alw+gVsdBXaKXuFxfvnY= | organizationId, role, validFrom, validUntil | /certificates/organization-membership |
oauthAppOwnership | Sigma | Bt68wMgcvQYryfNEEeP0NGSbpR8dyf3BRtafQPAM91s= | clientId, organizationId, verifiedAt | /certificates/oauth-app-ownership |
verifiedDomain | Sigma | PRRnjdcYrxjZoM3Xt7kCVE8oZLEHEmA/dVum7/adSbM= | domain, verificationMethod, verifiedAt, expiresAt | /certificates/verified-domain |
The ecosystem-owned IDs are existing compatibility contracts. Sigma-owned IDs use the published
canonical sigma:*:v1 definitions in the auth server, but applications should consume the literal
IDs from the catalog rather than recomputing them from display names.
Revocation freshness
Every Sigma certificate has a funded revocationOutpoint once production issuance is enabled. An
observed spend is enough for a verifier to stop trusting the certificate immediately. Under
Sigma's release policy, a requested revocation progresses through prepared, broadcast,
observed, and confirmed; Sigma reports it as final only after the required confirmation depth.
Revocation information becomes stale. A verifier should check the outpoint with current independent
chain data immediately before making a trust decision and should fail closed when current status is
unavailable. GET /api/certificates/status/{serialNumber} is Sigma's no-store observation endpoint,
not a replacement for signature verification or an independent chain check.
Public overlay privacy and retention
BRC-52 certificates are private in the wallet by default. Sigma does not currently advertise a live public certificate-overlay publication service.
Publishing a certificate, plaintext attribute, or revelation key to a public overlay is a separate, explicit disclosure. Overlay operators, indexers, caches, and recipients may copy and retain that data. Local relinquishment does not remove it, and later revocation marks a certificate invalid but does not erase prior copies. Applications should request only necessary fields, name the verifier, avoid public revelation keys, and explain retention before asking a user to publish anything.
Production endpoints
| Endpoint | Authentication | Current availability |
|---|---|---|
GET https://sigmaidentity.com/manifest.json | Public | Live BRC-68 trust document |
GET https://auth.sigmaidentity.com/.well-known/auth | Public | Live Sigma convenience metadata; not standard BRC-104 discovery |
POST https://auth.sigmaidentity.com/.well-known/auth | BRC-103 messages | Deployed handshake transport |
GET https://auth.sigmaidentity.com/api/certificates/types | Public | Live immutable catalog |
GET https://auth.sigmaidentity.com/api/certificates/eligibility?bapId=… | Signed-in Sigma session | Private account eligibility helper; not a BRC-100 wallet method |
POST https://auth.sigmaidentity.com/api/certificates/signCertificate | BRC-103 over BRC-104 | Deployed but issuance is currently disabled |
GET https://auth.sigmaidentity.com/api/certificates/status/{serialNumber} | Public | Deployed; depends on gated revocation infrastructure |
POST https://auth.sigmaidentity.com/api/certificates/revoke/{serialNumber} | Certificate subject over BRC-103/104 | Deployed; revocation infrastructure is not production-enabled |
GET https://auth.sigmaidentity.com/api/certificates/readiness | Public | Opaque rollout state; always HTTP 503 by design |
The detailed readiness endpoint is operator-only. It is not an application health check and does not authorize clients to bypass wallet permissions or attempt issuance while the public rollout state is disabled.
Account evidence and domain verification
The Credentials account page separates evidence collection from wallet issuance. A linked provider, verified email/phone, organization membership, or verified domain can establish eligibility for a corresponding type; it does not itself place a certificate in the wallet.
For an owned profile, GET /api/domain-verifications?bapId=… lists records. POST /api/domain-verifications accepts { bapId, domain, method, oauthClientId? } and returns a challenge with HTTP 201. The supported method values are dns and https. Complete the returned DNS/HTTPS instructions, then call POST /api/domain-verifications/{verificationId}/verify. Use the exact supported method and challenge returned by the service; do not fabricate a DNS record or treat a submitted domain string as verified ownership.
Wallet binding has separate challenge, verify, resolve, and revoke routes under /api/certificates/wallet-binding. Use the account wallet flow to prove both the account/profile association and wallet key. Ordinary session login or a copied public key is not wallet proof.
Public readiness is deliberately opaque: it always returns HTTP 503 and reports disabled or protected. protected is not a successful health check or an issuance authorization. Only the operator-only detailed readiness and an exercised supported wallet flow can establish operational readiness. The catalog and this reference do not turn on gated features.