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.

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

Prototype contract. The EasyAuths web approval page now verifies transaction-bound WebAuthn assertions. Embedded web/native SDKs, push delivery, managed attestation policy, and native-device enrollment remain roadmap work.

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.

Send a sandbox approval in minutes.

Request a trial