SessionKit docs

Security & versioning

How trust is established, what an attacker can and cannot do, and what we promise about upgrades.

SessionKit is the session layer of a wallet, so it is built on one rule: nothing is secret except private keys. The SDK, the protocol, and this documentation are all public. Anyone can read the code, fork it, or run it. Security comes from cryptography and user consent — never from obscurity.

How trust is established

Domain proof

Every BLAC Code carries an Ed25519 signature over its own contents, made by a key published at https://your-domain/.well-known/blac-session.json. The wallet fetches that document over TLS and verifies the signature before it shows anything to the user.

This means a scam site can run SessionKit — but it appears as its own domain, always. Impersonating you requires either your private key or a TLS certificate for your domain.

Consent

The approval screen shows the verified origin and every requested scope in plain language. Declining sends nothing at all — no user data exists anywhere until the moment of approval.

Pairwise identity

Each origin gets its own deterministically derived key pair, so the same user has a different id on every site. Two sites cannot compare notes and discover they share a user, and nobody gets a financial address unless they asked for one and the user agreed.

End-to-end encryption

P-256 ECDH between your session key and the wallet's, HKDF-SHA256 over a transcript that binds both public keys and the pairing topic, then AES-256-GCM for every message. Our relay forwards ciphertext it cannot read and stores nothing.

What an attacker can and cannot do

AttackOutcome
Claim to be your domain Blocked. Codes are signed by a key served from the real domain.
Swap in their own key on your code Blocked. The pairing topic is a hash of the key — a forged key can't match the scanned code.
Replay a captured login on another site Blocked. The proof is bound to both the origin and that one session.
Add scopes to a valid request Blocked. Any edit breaks the signature.
Compromise the relay Yields ciphertext and downtime. No plaintext, no valid session.
Reverse engineer the SDK or wallet Yields nothing. The protocol is published on purpose.
Show a victim a genuine code copied from your site Mitigated, not blocked. This is inherent to every scan-to-login system: a screenshot of a real code, shown to someone else, is still a real code. Codes expire within seconds, the approval screen names your origin, and the login lands only in the session that requested the code — see "What you must do".
Run a real scam site with a real domain Possible. See below.

The honest limit

Cryptography proves which domain minted a code. It cannot prove that domain is honest, and it cannot prove that the page showing the code belongs to that domain. A typosquat with a valid certificate verifies correctly as itself, and a copied code verifies correctly as yours.

Three things contain that:

  • BLACWALL domain reputation. Known-bad domains raise a hard warning in the approval screen; a domain the user has never connected to before is marked as new.
  • A minimal scope catalog. The most a malicious site can obtain is what the user explicitly approved on screen.
  • No money scope. No third-party session can move funds, so a bad decision costs an address, never a balance.

What you must do

  • Keep the private key server-side. Environment variable, never in the repo, never in client code.
  • Only sign for your own origin. Check fields.origin in your signing endpoint before signing. An open signing endpoint lets anyone borrow your identity.
  • Bind signing to the browser session that asked. Require your own session cookie or a CSRF token on the signing endpoint, remember which pairingTopic you signed for which session, and complete a login only into that session. A signing endpoint anyone can call mints genuine codes for anyone to relay; a session-bound one limits a relayed code to logging in the attacker's own session — which the short expiry then makes impractical.
  • Verify server-side. Call verifyApproval before you issue a cookie. The browser's word for who the user is means nothing on its own.
  • Rotate keys by publishing first. Add the new key to your well-known document, start signing with it, remove the old one after existing codes expire.

Versioning

The protocol version travels in the code itself, and BLAC Wallet speaks every version it has ever shipped. Your integration does not break behind your back.

  • Additive changes — new scopes, new optional fields — keep the same version. Ignore what you don't recognise and you're forward-compatible.
  • Breaking changes ship as a new version alongside the old one, with a deprecation window surfaced in the wallet before anything is retired.
  • The CDN URL is major-pinned. sessionkit.blaclabs.io/v1/ receives patches and security fixes automatically; a new major is a new URL you opt into.
  • We can kill a broken version without you. The wallet and relay can refuse a version immediately — no coordination, no waiting for sites to update.

Reporting a vulnerability

Email security@blaclabs.io. Please give us a reasonable window to ship a fix before publishing. Anything affecting user funds or cross-origin identity leakage is treated as critical and worked immediately.