Bitcoin request authentication
Sigma uses the bitcoin-auth package to produce and verify signed request tokens. Tokens identify a public key, signature scheme, timestamp, request path, and signature. Use the package rather than constructing the delimiter format manually.
Server-side OAuth client authentication
For an authorization-code or refresh exchange, sign the full path /api/auth/oauth2/token and the exact form-encoded request body. Send the result in X-Auth-Token. The signing public key must match the registered client's accountPubkey.
import { getAuthToken } from "bitcoin-auth";
export function signedTokenRequest(input: {
memberWif: string; fields: Record<string, string>;
}) {
const body = new URLSearchParams(input.fields).toString();
const token = getAuthToken({
privateKeyWif: input.memberWif,
requestPath: "/api/auth/oauth2/token",
body,
});
return {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"X-Auth-Token": token,
},
body,
};
}Run this on the server only. Preserve serialization and field order between signing and sending. Prefer exchangeCodeForTokens() for code exchange so the SDK constructs the expected request. See JavaScript for state/PKCE validation before this step.
Other signed routes
/api/backup/sync uses Authorization: Bitcoin-Auth … and checks that the signer controls the requested BAP identity. Its freshness check permits at most 300 seconds of clock skew. The ordinary backup GET also supports signed ownership access. Do not assume every API accepts this header or enforces the same signed-payload contract.
When building your own verifier, validate the expected request path, body, timestamp bounds, and authorized key in addition to the signature. A mathematically valid signature alone is not authorization for an arbitrary resource or protection against replay.
Legacy verification helper
POST /api/auth/token-for-endpoint accepts token, requestPath, and optional body and verifies a Bitcoin token. Its returned sessionToken is base64url-encoded JSON, not a signed JWT or a persisted Better Auth session. Do not use it as a bearer credential or trust it to authorize protected APIs. Use the real OAuth/session flow instead.
BRC-103/104 is different
Wallet-authenticated certificate and delegation routes use BRC-103 authentication over BRC-104 HTTP. Those messages are not interchangeable with X-Auth-Token, an OAuth bearer token, or a session cookie. See BRC standards and wallet credentials.
User signing remains local in the browser wallet or signer. The application member key used for token exchange is a separate server credential.