How cryptographic proof works
When a user taps ✅ Confirm in Telegram, Bondify generates a proof — a JWT signed with your project’s secret key using HMAC-SHA256. This proof encodes the user’s Telegram identity and the session metadata, and its signature can only be produced by someone who knows your secret key. Your server verifies the proof by callingverifyProof() from @bondify/server:
verifyProof() throws. You should catch that error, return a 401, and log the attempt.
Security checklist
Work through each item below before going to production:Never commit your Secret Key to version control
Store your Secret Key exclusively in environment variables (e.g.,
BONDIFY_SECRET_KEY=sk_live_...). Use a secrets manager (AWS Secrets Manager, HashiCorp Vault, Doppler, etc.) for production deployments. A committed key is a compromised key.Never embed the Secret Key in client-side code
The Secret Key belongs on your server — never in the browser, React/Vue/Angular bundles, React Native apps, Flutter apps, or any code that ships to a user’s device. Use the public-facing
project_id in client code and reserve the secret key for your backend only.Always verify the proof server-side
Call
verifyProof(proof, secretKey) on your server before creating any user session, writing to your database, or granting any access. Skipping verification means any attacker can log in as anyone by supplying a fake telegram_id.Always verify webhook signatures
Every webhook request from Bondify includes an
X-Bondify-Signature header containing an HMAC-SHA256 hex digest of the request body. Verify it before processing any webhook event:Handle all terminal session statuses in your UI
Always handle
cancelled and expired statuses gracefully — stop polling and show the user a clear message. Leaving these states unhandled can result in a broken UI that a confused user may abandon or, worse, retry in ways that create unexpected states.Use HTTPS only in production
All Bondify SDKs assume secure transport. Serving your app over plain HTTP in production means proofs and tokens can be intercepted in transit.
Never reuse expired or used session tokens
Sessions expire after 10 minutes. A session with status
expired or used cannot be revived. Generate a fresh session for each new login attempt — never reuse a token.Rotate your Secret Key if it is compromised
If your Secret Key is ever accidentally exposed (committed to git, logged, leaked via an error message), go to your project settings immediately and click Regenerate key. Then update
BONDIFY_SECRET_KEY on all servers and redeploy. The old key is invalidated the moment you regenerate.Secrets management
Recommended environment variable names:What Bondify protects against
Fake auth events
Every confirmed event carries an HMAC-SHA256 signed proof. An attacker cannot fabricate a valid proof without your secret key — even if they intercept a real proof in transit.
Replay attacks
Sessions are single-use. Once a proof is consumed by
verifyProof(), the session moves to used and the same proof cannot be replayed to log in again.Identity impersonation
The
telegram_id inside a proof is bound to the Telegram account that actually confirmed the session. Telegram’s own account verification ensures the identity is real — Bondify’s signature ensures it wasn’t tampered with on the way to your server.Unsigned webhook events
Every webhook payload is signed with your secret key. Your server can reject any unsigned or incorrectly signed request before it touches your business logic.
Next steps
Authentication Flow
See exactly where
verifyProof() fits in the end-to-end flow.Projects
Learn how to rotate your secret key from the project settings page.