Your challenge. Your verifier.
Your website supplies the challenge and verification endpoints on its own origin. Your backend stores and atomically consumes the challenge, checks the returned proof and issues a fresh local session.
Developer guide · Sign-in
Give users a simple sign-in approved on their device. Add the RK-1 button or choose registered OIDC; your backend verifies the result and creates its own session. Rhea Data is not required.
Simple developer integration
This is public integration documentation—no Rhea Key account or sign-in is required to read or copy it. The RK-1 web button takes two lines to present on your own website. Your website—not rhea.llc—issues the single-use challenge, verifies the signed response on its backend and creates the session. Rhea Data is not required.
RK-1 is the Rhea Key protocol, version 1: passwordless cryptographic sign-in. No password is typed, sent or stored.
Add to your website · RK-1 button
<script src="https://rheakey.com/sdk/rhea.js" async></script>
<rhea-button app-name="Your Website"></rhea-button>This code is shown as text for developers to copy. It is not loaded or executed by the Rhea corporate website.
The button uses your site's same-origin POST /rhea-challenge, opens Rhea Key for QR/number matching or same-device approval, then submits the signed proof to POST /rhea-verify. The rhea-success event fires after your verification endpoint succeeds.
Integration skeleton—not a standalone runnable server: you must supply the route handlers, atomic challenge store, session creation, error handling and your real domain/origin. Request the current integration package and its installation instructions from Rhea. An npm publication is not assumed by this skeleton.
Server · RK-1 verifier skeleton
// Your server: obtain the Rhea Key integration package first.
import { createRk1Verifier, readRk1Cookie } from "@rheakey/sdk/rk1";
import { verifyMessage } from "ethers";
const rk1 = createRk1Verifier({
domain: "app.example.com",
origin: "https://app.example.com",
recoverAddress: verifyMessage,
store: atomicSharedStore, // Your Redis GETDEL / SQL DELETE RETURNING store
});
// POST /rhea-challenge
const issued = await rk1.issueChallenge();
res.setHeader("Set-Cookie", issued.setCookie);
res.json(issued.body);
// POST /rhea-verify
const user = await rk1.verify({
cookieId: readRk1Cookie(req.headers.cookie),
body: req.body,
});
await createFreshAppSession(user.address); // Your session implementation
res.setHeader("Set-Cookie", rk1.clearCookie);
res.sendStatus(204);Scan once, confirm two digits and approve. On a phone, participating sites can open Key directly.
Use the RK-1 drop-in button or the registered OIDC client. No Rhea Data integration required.
Your backend checks origin, stored nonce, expiry, signature and replay before creating its own fresh session.
Include your website domain, runtime and preferred integration path so Rhea can provide the relevant package and registration requirements.
Start here
Direct RK-1 verifies a device-signed proof. Registered-client OIDC verifies an issuer token. In both paths, the participating website validates the result and creates its own session.
Your website supplies the challenge and verification endpoints on its own origin. Your backend stores and atomically consumes the challenge, checks the returned proof and issues a fresh local session.
Use the documented issuer and discovery configuration with authorization code and PKCE. Your backend verifies the returned token before issuing its own local session.
A · Direct RK-1
Prerequisites: your relying domain and origin, a signer recovery function, server-side challenge storage and an HttpOnly cookie binding the browser to its challenge. The current SDK defaults to 120 seconds and caps challenge lifetime at 120 seconds.
Your backend receives a challenge request on your origin.
→ stores a single-use challenge bound to the browser by an HttpOnly cookie
The browser opens Rhea Key and receives a site-bound signed response.
→ presentation completes, but no trusted session exists yet
Your backend atomically consumes the stored challenge and verifies the response.
→ only a valid proof creates your own fresh session
Check domain, origin, stored nonce, stored timestamps, expiry, signer against the stored challenge. Consume that challenge atomically so two requests cannot both succeed. Never trust only a frontend event or a nonce supplied by the returning browser.
memoryStore is single-instance and in-process. Distributed deployments need an atomic shared take/delete store; independent memory stores on several instances are not a substitute.
B · OIDC
Prerequisites: a registered client ID, the documented issuer configuration, the integration package and an application backend that verifies the token and establishes its own session. No client secret belongs in frontend code.
The client supports sign-in and redirect completion; the backend uses token verification before session creation. Confirm the exact package imports and recipe in the distributed documentation. Do not use client_secret_basic: the documented methods are client_secret_post or none.
Validate these issuer and discovery settings in your deployment. Hardware assurance fields acr/amr are device-reported, not hardware attestation or certification.
Browser / server
| Path | Browser | Your backend |
|---|---|---|
| Direct RK-1 | Opens Key and passes the signed response back. | Issues and stores a browser-bound challenge; atomically consumes it; verifies bindings, time and signer; creates a fresh session. |
| OIDC | Uses the registered client and PKCE sign-in/redirect flow. | Verifies the token for the client, then creates its own session. Holds any required client secret server-side. |
Direct RK-1 failure handling
The response belongs to a different site. Reject it and check the configured relying domain; do not relax domain binding.
The sign-in window has elapsed. Start a fresh challenge instead of extending or reusing this one.
No stored challenge is available for this browser attempt. It may be missing or already consumed. Restart sign-in; never accept the response on its own.
The challenge store cannot complete the operation. Fail closed and restore the store before retrying; do not issue a session.
Deployment checklist
Choose direct RK-1 or OIDC and request the current integration package and installation instructions. Do not mix their endpoint or token contracts.
For direct RK-1, confirm domain/origin binding, HttpOnly browser binding and the maximum 120-second challenge window.
For multi-instance direct deployments, prove the shared store consumes a challenge atomically. Test replay, expiry, missing challenge and store failure.
For OIDC, confirm registered client ID, code + PKCE S256, accepted scopes, ES256 and the documented token-authentication method.
Verify the response on your backend and issue a fresh local session only after success. Never accept a frontend event as proof.
Keep secrets server-side. Treat device-reported assurance separately from hardware attestation; test actual cloud and device behavior in your own deployment.
Continue
Return to the product overview or explore the other integration guides.