DEV Community

Cover image for How to future-proof your web app's password authentication
Tide Foundation
Tide Foundation

Posted on • Originally published at tide.org

How to future-proof your web app's password authentication

TL;DR

Declare:

const { login } = useTideCloak();
Enter fullscreen mode Exit fullscreen mode

Add this:

<p><button onClick={login}>Login</button></p>
Enter fullscreen mode Exit fullscreen mode

That's it. No password storage, no hashing logic.

Some context

Traditional authentication knows dangerously too much. Its sole job is to determine whether users are who they claim to be, and nothing more. Yet today's systems must both know how to challenge users (password/biometric) and decide if they're valid. Whether you hash and salt passwords locally or use OAuth via a provider like Okta or Facebook, someone still holds secrets. When that someone is compromised, because you trusted them implicitly, you absorb the fallout.

It feels unavoidable. But what if authentication could verify a user without sending or storing secrets anywhere, and without trusting any single party to act as the authority? That's what we're building with TideCloak.

The problem with current approaches

  • Password hashes are targets. Modern GPU clusters can test billions of combinations per second; offline attacks thrive on stolen hashes.
  • Social login shifts trust. You're now betting on the provider's security posture. Credentials (or their derivatives) still exist somewhere and can be attacked offline.

How it works

Instead of storing credentials, TideCloak converts each credential into a zero-knowledge proof of a challenge that only the rightful holder can solve, then shards that proof across a network of independent nodes. No single node holds enough to reconstruct any meaningful proof, or to act as the sole authority to validate it. During login, the user engages the network to obtain a short-lived proof. The user's credential becomes effectively ineffable - beyond the ability to be expressed anywhere, by anyone.

INEFFABLE /ɪnˈɛfəbəl/ (adj) - too great to be expressed.

Zero-knowledge Authentication with TideCloak

Sequence (at a glance):

  1. The user clicks Login, launching a login screen with a secret session bound to the browser.
  2. The user enters their Username and Password, performing a zero-knowledge authentication using Tide's PRISM protocol, against the network.
  3. A correctly entered credentials will manifest a cryptographic proof from the network.
  4. Using that proof, TideCloak sends your app an OAuth2 Access Token (JWT) bound to the secret browser session.

Unique properties and benefits:

  • Best of both worlds: Familiar, frictionless UX, but passkey level security.
  • User privacy and identity ownership: Each user receives a deterministic, app-scoped, anonymized identity (untraceable and unlinkable across apps). Their master credentials are trusted to no one.
  • Nothing to steal: no password database, no hashes, no secrets at rest - Rendering offline attacks (e.g. Rainbow) infeasible.
  • Provable integrity: network-level and browser-level verification ensure tamper resistance and trust.
  • Any MITM tampering causes authentication to fail.
  • Resilient against token hijacking. The JWT is unusable outside its originating browser.

And the implementation looks like this

Create a React app using Vite

npm create vite@latest tidecloak-react -- --template react-ts
cd tidecloak-react
npm install @tidecloak/react
Enter fullscreen mode Exit fullscreen mode

Get TideCloak running
Run a local test instance with Docker:

sudo docker run --name tidecloakdev \
  -d \
  -v .:/opt/keycloak/data/h2 \
  -p 8080:8080 \
  -e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
  -e KC_BOOTSTRAP_ADMIN_PASSWORD=change-me-now \
  tideorg/tidecloak-dev:latest
Enter fullscreen mode Exit fullscreen mode

Tip: Ports 8080 (server) and 5173 (Vite) must be free.

Activate your TideCloak instance
Tide offers a free developer license for up to 100 users.

  1. Open: http://localhost:8080/admin/master/console/#/myrealm/identity-providers/tide/tide/settings
  2. Sign in (Username: admin, Password: change-me-now, unless changed). You'll land on: myrealm realm → Identity Providers → tide IdP → Settings screen.
  3. Click Manage License → Request License.
  4. Complete the checkout with a contact email.

Within a few seconds, your TideCloak host should be licensed and activated.

Export your TideCloak adapter

  1. Go to Clients → mytest
  2. Set Valid redirect URIs to http://localhost:5173/*
  3. Set Web origins to http://localhost:5173
  4. In Clients menu → mytest client ID → Action dropdown → Download adaptor configs option (keep it as keycloak-oidc-keycloak-json format)
  5. Download as tidecloak.json in your project root

Edit src/main.tsx
Add imports:

import { TideCloakContextProvider, useTideCloak, Authenticated, Unauthenticated } from '@tidecloak/react'
import tidecloakConfig from "../tidecloak.json"
Enter fullscreen mode Exit fullscreen mode

Pre-authentication view:

function Welcome() {
  const { login } = useTideCloak();
  return (
    <div>
      <h1>Hello!</h1>
      <p>Please authenticate yourself!</p>
      <p><button onClick={login}>Login</button></p>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Post-authentication view:

function LoggedIn() {
  const { logout } = useTideCloak();
  return (
    <div>
      <p>You're signed in!</p>
      <button onClick={logout}>Logout</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Mount the app:

createRoot(document.getElementById('root')!).render(
<StrictMode>
  <TideCloakContextProvider config={tidecloakConfig}>
    <Authenticated>
      <LoggedIn />
    </Authenticated>
    <Unauthenticated>
      <Welcome />
    </Unauthenticated>
  </TideCloakContextProvider>
</StrictMode>,
)
Enter fullscreen mode Exit fullscreen mode

Build and run

npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

Technical properties
TideCloak uses ineffable cryptography where authentication requires collaboration from multiple nodes, and no single node - or any subset below a threshold - can reconstruct credentials or proofs. This is a novel form of secure multi-party computation, validated through published research with RMIT and Deakin universities.

Key properties:

  • Threshold: authentication succeeds if any 14 of 20 nodes respond.
  • Resilience: compromising up to 14 nodes reveals nothing.
  • Unlinkability: each service sees users as unique, unlinkable identifiers (app-scoped).
  • Performance: on par with, or better than, major cloud IdPs; browser-bound proofs add negligible overhead.

Threat model and limitations
Protects against:

  • Database breaches revealing credentials/hashes
  • Insider access to user password material
  • Token replay in MITM scenarios (browser-bound, DPoP-style proof)
  • OAuth/IdP provider compromise leaking user credentials

Doesn't protect against:

  • Keyloggers/malware on user devices
  • Very weak passwords
  • Majority network compromise above threshold (≥14/20)

Current limitations:

  • Internet connectivity required for authentication
  • Alpha stage - not recommended for production yet

Integration simplicity

The SDK handles the cryptography. Your app calls useTideCloak() and receives a session token. Standard JWT verification works normally.
For existing systems, run traditional auth and zero-knowledge auth on TideCloak in parallel during migration, moving users over as they log in.

Open questions we're working on

We're in alpha and looking for feedback on:

  • Developer experience
  • Clarity of the approach
  • Bugs and feature requests

TideCloak's code is open source - we welcome security reviews and integration feedback.

Dive into the code

We're building this because credentials shouldn't be honeypots, individuals should own their identities, and organizations shouldn't have to carry the liability of securing secrets.

⚠️ Currently Alpha release: not for production use yet. Free developer license (up to 100 users). See Terms.

Top comments (0)