EasyAuths for developers
Approval infrastructure, not another identity stack.
Keep your frontend, users, sessions, and business logic. EasyAuths handles the narrow security ceremony between “someone asked” and “the action may execute.”
You own
Application UI, primary login, user profile, business data, and execution logic.
EasyAuths owns
Challenges, factor signatures, policy evaluation, signed receipts, consumption, and audit.
1. Create the exact transaction
Create transactions only from your backend. Protected fields are canonicalized and included in the receipt digest; changing one requires a new approval.
const response = await fetch("https://auth.example.com/api/v1/transactions", {
method: "POST",
headers: {
"Authorization": "Bearer $EASYAUTHS_API_KEY",
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json"
},
body: JSON.stringify({
requesterId: "user_123",
recipientLabel: "Finance approvers",
applicationId: "app_ledger",
actionType: "MONEY_MOVEMENT",
title: "Approve vendor wire",
protectedResource: "Operating ••4821 → Vendor ••9077",
purpose: "Invoice AP-8842",
amount: 24750,
currency: "USD",
interactionMode: "OUT_OF_BAND",
requiredApprovals: 1,
requireSeparation: true,
expiresInMinutes: 5
})
});
const transaction = await response.json();2. Choose the interaction mode
The transaction contract reserves modes for approval inside a customer UI or through a separately enrolled EasyAuths app. Receipts report the interaction mode and verified proof type actually recorded.
- SAME_APP_WEB: implemented for the EasyAuths-hosted web ceremony; an embeddable customer SDK is planned.
- SAME_APP_IOS / ANDROID: planned signed approval within the customer application's native context.
- OUT_OF_BAND: planned independently enrolled app retrieval and push delivery; request display is represented by the current web prototype.
3. Consume before execution
Never execute from a client callback. Your backend retrieves the authoritative decision, atomically consumes it, and verifies the receipt audience and digest.
const result = await easyauths.transactions.consume(transaction.id, {
applicationId: "app_ledger"
});
// Verify the ES256 receipt against the tenant JWKS.
if (result.state !== "CONSUMED") {
throw new Error("Approval was not consumed");
}
await executeProtectedAction();Focused API surface
Every credential is bound to one application and environment. Collection and item reads return only that application's transactions; use the opaque cursor to advance through a filtered collection.
- GET
- /api/v1/transactions?limit=25&state=PENDING
- POST
- /api/v1/transactions
- GET
- /api/v1/transactions/:id
- POST
- /api/v1/transactions/:id/cancel
- POST
- /api/v1/transactions/:id/consume
- GET
- /api/v1/audit
- GET
- /api/v1/jwks
The approve/deny application endpoints remain a demo-adapter surface and require a non-provisionable scope. Production human decisions will use the separate transaction-bound WebAuthn ceremony.