Hades Auth
raw JSON → 1.0.63 verified Mon Apr 27 auth: no javascript
Hades Auth is a client-side authentication library (v1.0.63) that uses elliptic-curve cryptography (ECDSA with P-384) for public/private key identity. It provides functions to generate key pairs, onboard devices, sign requests, and wrap fetch calls with signed headers. Unlike token-based auth (JWT/sessions), it never sends secrets to the server; only public keys are stored, making database leaks less catastrophic. The library is ESM-only, ships TypeScript definitions, and is actively released on npm. It is designed for browser use (uses Web Crypto API) and includes a fetch wrapper that automates request signing. The package is maintained by OracularHades.
Common errors
error Error [ERR_REQUIRE_ESM]: require() of ES Module /path/to/node_modules/hades-auth/src/index.js from /path/to/your/file.js not supported. ↓
cause Using require() on an ESM-only package.
fix
Replace require('hades-auth') with import ... from 'hades-auth' or use dynamic import('hades-auth').
error TypeError: fetch_wrapper is not a function ↓
cause Attempted to use fetch_wrapper as a default or incorrect import. The package exports named exports.
fix
Use import { fetch_wrapper } from 'hades-auth'.
error Uncaught (in promise) TypeError: Failed to execute 'importKey' on 'SubtleCrypto': parameter 2 is not of type 'ArrayBuffer'. ↓
cause Private key or public key passed to sign/onboard is not a valid PEM string or is malformed.
fix
Ensure you are passing the exact string returned by generate_new_credentials or stored properly.
Warnings
breaking Package is ESM-only. Using require() will cause ERR_REQUIRE_ESM. Must use import or dynamic import(). ↓
fix Use import syntax in your project; if you cannot switch to ESM, use dynamic import() with await or promise.
gotcha When using fetch_wrapper with Express and JSON body parser, you must set Content-Type to application/json. Otherwise Express treats body as empty. ↓
fix Explicitly set 'Content-Type': 'application/json' in fetch options when sending JSON.
deprecated No functions are deprecated yet. Always check changelog. ↓
fix N/A
gotcha Private key must be in PEM format as returned by generate_new_credentials. Passing an incorrect format will cause signing to fail silently or throw. ↓
fix Always store and retrieve the private_key string exactly as produced by generate_new_credentials.
Install
npm install hades-auth yarn add hades-auth pnpm add hades-auth Imports
- generate_new_credentials wrong
const { generate_new_credentials } = require('hades-auth')correctimport { generate_new_credentials } from 'hades-auth' - sign
import { sign } from 'hades-auth' - fetch_wrapper
import { fetch_wrapper } from 'hades-auth' - onboard_new_device
import { onboard_new_device } from 'hades-auth' - default wrong
import * as hadesAuth from 'hades-auth'correctimport hadesAuth from 'hades-auth'
Quickstart
import { generate_new_credentials, onboard_new_device, fetch_wrapper } from 'hades-auth';
// Client: generate key pair
async function register() {
const creds = await generate_new_credentials();
localStorage.setItem('private_key', creds.private_key);
// Send public_key to server
const response = await fetch('/api/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ public_key: creds.public_key })
});
const { device_id } = await response.json();
localStorage.setItem('device_id', device_id);
}
// Server: verify public key
// (in an Express-like handler)
app.post('/api/register', async (req, res) => {
try {
const verification = await onboard_new_device(req.body.public_key);
// Store public_key with verification.deviceid (or custom ID)
res.json({ device_id: verification.deviceid });
} catch (e) {
res.status(400).json({ error: 'Invalid key' });
}
});
// Client: signed request
async function fetchData() {
const privateKey = localStorage.getItem('private_key');
const deviceId = localStorage.getItem('device_id');
const response = await fetch_wrapper('https://api.example.com/data', {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
}, deviceId, privateKey);
return response.json();
}