Sign-in with no passwords to steal

Passkeys, one-time codes, magic links and social login behind one OpenID Connect (OIDC) issuer. Your users sign in on a page that carries your organization's branding. You get a signed token. Behind both, each person's profile sits in an encrypted Ingot.

Your issuer: https://auth.sparkvault.com/acc_xxx

The SparkVault sign-in popup: a Sign in heading, one email address field and a Continue button
SparkVault's own sign-in runs on Identity. Yours carries your name, logo and colors.

Four ways to sign in, all of them passwordless

You choose which methods to offer in your Identity settings. Whichever one a person uses, they end up as the same SparkVault ID (SVID).

Sign-in methods and what each one does
Method What the person does What to know
Passkeys Approves with a fingerprint, a face or a device PIN, through WebAuthn and FIDO2. The account holds the credential's public key and nothing a thief could replay.
One-time codes Types a six-digit code sent by email, SMS or voice call. SMS and voice codes are included in the Identity price.
SparkLinks Clicks a single-use link in an email and is signed in. The link expires after 15 minutes by default. A mail scanner that opens it cannot use it up: the link burns only when the page's script confirms it.
Social login Signs in with Google, GitHub, Apple, Microsoft, LinkedIn or Facebook. The provider's subject is linked to the person's SVID, so the same person stays the same person.

Sign in once on one of your domains and the next one offers a one-click “Continue as …” through a 30-day single sign-on (SSO) session on the Identity origin.

Add it with a button and a token check

The SDK opens the sign-in popup and hands back a signed JSON Web Token (JWT). Your backend verifies it against the account's public keys and maps your own user record by SVID. Your app keeps its profile and authorization model; Identity handles the proof.

For a standard flow, the same issuer speaks OIDC authorization code with PKCE (Proof Key for Code Exchange), so any OIDC library can discover it.

Read the JavaScript SDK reference

In the browser

const sv = SparkVault.init({ accountId: 'acc_your_account_id' });

document.querySelector('#login-btn').onclick = async () => {
  const { identity, token } = await sv.products.identity.signIn();
  console.log(identity, token);  // "user@example.com", "eyJhbG..."
};

On your server

import * as jose from 'jose';

const ISSUER = 'https://auth.sparkvault.com/acc_xxx';
const JWKS = jose.createRemoteJWKSet(new URL(`${ISSUER}/.well-known/jwks.json`));

const { payload } = await jose.jwtVerify(token, JWKS, {
  issuer: ISSUER,
  audience: 'acc_xxx',
  algorithms: ['EdDSA']
});
const svid = payload.svid || payload.sub;

Discovery document at /.well-known/openid-configuration

{
  "issuer": "https://auth.sparkvault.com/acc_example",
  "authorization_endpoint": "https://auth.sparkvault.com/acc_example/authorize",
  "token_endpoint": "https://auth.sparkvault.com/acc_example/token",
  "jwks_uri": "https://auth.sparkvault.com/acc_example/.well-known/jwks.json",
  "grant_types_supported": ["authorization_code", "refresh_token"],
  "id_token_signing_alg_values_supported": ["EdDSA", "RS256"],
  "code_challenge_methods_supported": ["S256"],
  "scopes_supported": ["openid", "email", "phone", "profile"]
}

Under the hood, every person is an Ingot

The same encrypted storage that holds your files holds your users. Each person is one Structured Ingot in SparkVault's Identity Vault, a shared directory Vault that customers cannot reach through the Vault API. The SVID is the Ingot's ID.

The main keys inside one person's Ingot

ing_019e6f58f7d27c6ebe93cf08b1e6c19b   (the SVID)
  profile          name parts, AKAs
  emails           email, verified_at, is_primary
  phones           phone, verified_at, is_primary
  passkeys         credential ID, public key
  social           provider, subject, linked_at
  authenticators   TOTP seed, encrypted
  two_factor       enabled, enrolled_at
  recovery_codes   SHA-256 hashes, used_at
  merged_svids     absorbed SVIDs
Verified only
An email, phone or social identifier is written to the Ingot only once the person has proved they control it.
Passkeys
The Ingot keeps the credential ID, the public key and a signature counter. The private key never reaches SparkVault.
Authenticator apps
A Time-based One-Time Password (TOTP) seed is encrypted at rest in the Identity Vault.
Recovery codes
Stored as SHA-256 hashes. The plaintext is shown to the person once, and a used code is marked used.
Finding a person
The index that maps an email address or phone number to an Ingot stores a SHA-256 hash of it, never the address.
Off the hot path
The Ingot holds durable identity facts only. Sessions, activity and lockdown state live in separate stores, which keeps the Ingot off the login hot path.

Tokens expire fast and sessions can be killed

A signed token proves who signed in. A managed session decides how long that proof keeps working, and the person can end it.

Access token
15 min
Typical lifetime, 900 seconds, then a refresh.
Session, sliding
30 days
Each refresh moves the expiry 30 days out.
Session, hard cap
90 days
No amount of refreshing goes past it.
Refresh grace
30 s
The just-replaced refresh token stays valid this long.

What checks what

Every account signs with its own keys, and the public half is published for your verifier to fetch.

Signatures
Ed25519 (EdDSA) by default. An OIDC client can opt in to RS256 for stacks whose JWT library has no EdDSA support, .NET being the common one. The key set publishes both, and verifiers pick by kid.
PKCE
Required, with the S256 method only.
Refresh
Refresh tokens rotate on every use. The session stores a hash of the refresh token, not the token.
Revocation
/revoke deletes the session, and /introspect lets your server confirm an access token is still live. Introspection is for confidential clients only.
Lockdown
Revokes every live session and makes older access tokens inactive. A site the person blocks can no longer log them in, refresh their token or pass introspection.
Signing out
Ending your app's session does not end the person's SSO session, so the next click is a one-click “Continue as …”. They can end it themselves.
The auth.sv Security page: an Identity protected summary, two registered passkeys with Remove buttons, an Add a passkey button and an authenticator app

People run their own account at auth.sv

auth.sv belongs to the person, not to your company. They see their active sessions and the sites they have signed into, manage verified emails, phones and passkeys, turn on two-factor authentication, and lock their account down. You build none of it.

The one thing a person can make public is a photo. It is served from my.auth.sv as a plain image URL you can drop into an img tag, and a person who has no photo, or who switched it off, gets the same neutral placeholder.

Read the auth.sv avatar reference

What it costs

See the Identity pricing

Identity is priced in tiers by monthly logins, and SMS and voice one-time codes are included. The tiers and their prices are listed on the pricing page, published in full.

Try the sign-in on your own app

Create an account, copy your account ID into the SDK, and attach sign-in to a button.