Skip to content

Developer guide · Sign-in

Add Rhea Key sign-in to your website.

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

One familiar sign-in. Your website stays in control.

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.

What is RK-1?

RK-1 is the Rhea Key protocol, version 1: passwordless cryptographic sign-in. No password is typed, sent or stored.

  1. Your server issues a single-use challenge bound to this browser.
  2. The person approves in Rhea Key; their device signs the challenge.
  3. Only the signed proof returns—the private key is not sent to the website.
  4. Your backend verifies the proof once, then creates its own session.
Request the RK-1 integration package Full RK-1 security and deployment requirements

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.

See the server verification contract

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);

Easy for people

Scan once, confirm two digits and approve. On a phone, participating sites can open Key directly.

Easy for websites

Use the RK-1 drop-in button or the registered OIDC client. No Rhea Data integration required.

Secure by responsibility

Your backend checks origin, stored nonce, expiry, signature and replay before creating its own fresh session.

Request the RK-1 integration package Request OIDC client registration

Include your website domain, runtime and preferred integration path so Rhea can provide the relevant package and registration requirements.

Start here

Choose the protocol that fits your website.

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.

A · Direct RK-1

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.

B · OIDC

A registered client. A verified token.

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

Bind the challenge to the browser. Consume it once.

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.

  1. 01

    Your backend receives a challenge request on your origin.

    → stores a single-use challenge bound to the browser by an HttpOnly cookie

  2. 02

    The browser opens Rhea Key and receives a site-bound signed response.

    → presentation completes, but no trusted session exists yet

  3. 03

    Your backend atomically consumes the stored challenge and verifies the response.

    → only a valid proof creates your own fresh session

Endpoints hosted by the relying website

POST /rhea-challenge
Your server issues the challenge and binds it to this browser attempt. This is not a Rhea API endpoint.
POST /rhea-verify
Your server consumes and verifies the proof. These endpoint names describe the relying-site integration recipe, not endpoints provided by this corporate website.

Documented verifier interface

Exports
createRk1Verifier · readRk1Cookie · memoryStore
createRk1Verifier options
domain · origin · recoverAddress · store (optional) · ttlSeconds (optional)
Returned methods
issueChallenge() · verify({cookieId,body})

Verification is more than a valid signature.

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

Use the registered-client flow. Verify the token server-side.

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.

Issuer
https://rheakey.com
Discovery
https://rheakey.com/.well-known/openid-configuration
Flow
Authorization code + PKCE S256
Scopes
openid / profile
Signing algorithm
ES256
Token authentication
client_secret_post or none

API reference

  • createRheaClient({clientId})
  • signIn()
  • signInWithRedirect()
  • completeRedirect()
  • RheaSignInButton
  • verifyRheaToken(idToken,{clientId})

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

Keep the two responsibilities separate.

Browser and backend responsibilities for each integration
PathBrowserYour backend
Direct RK-1Opens 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.
OIDCUses 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

Reject the attempt. Fix the cause. Start fresh.

DOMAIN_MISMATCH

The response belongs to a different site. Reject it and check the configured relying domain; do not relax domain binding.

EXPIRED

The sign-in window has elapsed. Start a fresh challenge instead of extending or reusing this one.

NO_CHALLENGE

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.

STORE_UNAVAILABLE

The challenge store cannot complete the operation. Fail closed and restore the store before retrying; do not issue a session.

Deployment checklist

Validate your integration before accepting sign-ins.

  1. 01

    Choose direct RK-1 or OIDC and request the current integration package and installation instructions. Do not mix their endpoint or token contracts.

  2. 02

    For direct RK-1, confirm domain/origin binding, HttpOnly browser binding and the maximum 120-second challenge window.

  3. 03

    For multi-instance direct deployments, prove the shared store consumes a challenge atomically. Test replay, expiry, missing challenge and store failure.

  4. 04

    For OIDC, confirm registered client ID, code + PKCE S256, accepted scopes, ES256 and the documented token-authentication method.

  5. 05

    Verify the response on your backend and issue a fresh local session only after success. Never accept a frontend event as proof.

  6. 06

    Keep secrets server-side. Treat device-reported assurance separately from hardware attestation; test actual cloud and device behavior in your own deployment.

Continue

Continue with Rhea Key.

Return to the product overview or explore the other integration guides.