Overview
Sigma Auth issues BRC-52/53 identity certificates that cryptographically attest to verified facts about a user, such as linked social accounts or verified email addresses. Certificates are signed by the Sigma Auth certifier and can be verified by any party using the certifier's public key.
Certificate issuance follows a two-step nonce handshake (BRC-53 protocol) to prevent replay attacks and ensure both parties contribute entropy to the certificate serial number.
Certificate Types
List Available Types
GET /api/certificates/types
Returns all certificate types the server can issue. No authentication required.
Response:
{
"types": [
{
"id": "social-link",
"typeId": "base64-encoded-sha256-hash",
"name": "Social Link",
"description": "Verifies ownership of a social media account linked to a BAP identity",
"fieldsSchema": { "type": "object", "required": ["bapIdentityKey", "provider", "accountId", "handle", "verifiedAt"] }
},
{
"id": "verified-email",
"typeId": "base64-encoded-sha256-hash",
"name": "Verified Email",
"description": "Verifies ownership of an email address linked to a BAP identity",
"fieldsSchema": { "type": "object", "required": ["bapIdentityKey", "email", "domain", "verifiedAt"] }
}
]
}Certificate Issuance (Two-Step Flow)
Step 1: Initial Request
POST /api/certificates/initialRequest
Starts the certificate issuance handshake. Requires authentication.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
clientNonce | string | Yes | Client-generated 32-byte hex nonce |
certificateType | string | Yes | Base64-encoded certificate type ID |
Response:
{
"validationKey": "hex-string-64-chars",
"serialNumber": "base64-encoded-32-bytes",
"serverNonce1": "hex-string-64-chars",
"serverNonce2": "hex-string-64-chars"
}The validationKey is derived as SHA256(clientNonce || serverNonce1). The serialNumber is Base64(SHA256(clientNonce || serverNonce2)). Pending requests expire after 10 minutes and can only be consumed once.
Step 2: Sign Certificate
POST /api/certificates/signCertificate
Submits the Certificate Signing Request (CSR) with encrypted fields and keyring. The server validates the nonce, signs the certificate, and persists it. Requires authentication.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
messageType | string | Yes | Must be "CertificateSigningRequest" |
certificateType | string | Yes | Base64-encoded certificate type ID |
clientNonce | string | Yes | Same nonce from Step 1 |
validationKey | string | Yes | Validation key received in Step 1 |
serialNumber | string | Yes | Serial number received in Step 1 |
fields | object | Yes | Encrypted certificate field values (Base64 per field) |
keyring | object | Yes | Encrypted symmetric keys per field (Base64) |
serverNonce | string | Yes | Server nonce from Step 1 |
Response:
{
"certificate": {
"serialNumber": "base64",
"typeId": "base64",
"subject": "compressed-pubkey-hex",
"certifier": "compressed-pubkey-hex",
"revocationOutpoint": "txid.vout",
"fields": { "fieldName": "base64-encrypted-value" },
"signature": "der-hex-encoded",
"masterKeyring": { "fieldName": "base64-encrypted-key" }
},
"certifierPublicKey": "compressed-pubkey-hex"
}Certificate Status
Check Certificate Status
GET /api/certificates/status/{serialNumber}
Returns the status of an issued certificate. No authentication required. Does not return encrypted field values.
Response:
{
"serialNumber": "base64",
"typeId": "social-link",
"certifier": "compressed-pubkey-hex",
"subject": "compressed-pubkey-hex",
"revoked": false,
"revokedAt": null,
"createdAt": "2026-03-23T20:00:00.000Z"
}Error Responses:
404- Certificate not found
Certificate Revocation
Revoke a Certificate
POST /api/certificates/revoke/{serialNumber}
Revokes a previously issued certificate. Only the certificate subject (the authenticated user who owns it) can revoke. Requires authentication.
Response:
{
"revoked": true,
"serialNumber": "base64",
"revokedAt": "2026-03-23T21:00:00.000Z"
}Error Responses:
401- Not authenticated403- Not the certificate subject404- Certificate not found409- Certificate already revoked