Quorum Auth is a framework-agnostic TypeScript engine for decisions that should not be made by one person alone. It coordinates authenticated participant responses for multi-party authentication, consent, approvals, and consensus.
The core answers whether a proposal has received sufficient valid responses. It does not authenticate people by itself and it does not execute business actions.
Version 0.1.0 is the foundation release. It includes the proposal lifecycle, participant roles, pluggable credentials and policies, deterministic payload binding, single-use challenges, HMAC resolution tokens, and an in-memory adapter for development and tests.
The in-memory adapter is not a production database. Production adapters must provide durable storage and atomic state transitions.
| Guide | Purpose |
|---|---|
| Getting started | Install the package and create a first consent workflow. |
| Architecture | Understand the core abstractions and trust boundaries. |
| API reference | Review the public interfaces and methods. |
| Plugin guide | Build policies, credentials, hooks, and transport integrations. |
| Security model | Understand security guarantees, limitations, and reporting. |
| Contributing | Set up development and submit changes. |
| Release guide | Build, test, package, and publish a release. |
npm install @quorum-auth/coreimport { createQuorumAuth, consentPolicy } from "@quorum-auth/core";
const policy = consentPolicy();
const auth = createQuorumAuth({
secret: process.env.QUORUM_SECRET!,
plugins: [
{
id: "example",
policies: [policy],
credentials: [{
id: "demo-credential",
async verifyProof({ proof }) {
return proof === "demo-proof";
},
}],
},
],
});
const proposal = await auth.createProposal({
type: "household_transfer",
purpose: "CONSENT",
initiatorId: "husband",
participants: [{
principalId: "wife",
role: "CONSENT_REQUIRED",
canRespondWith: ["CONSENT", "REJECT", "OBJECT"],
}],
policy: { id: "consent" },
audience: "payments-api",
payload: { amount: 2500, currency: "USD", destination: "shared-savings" },
});
const challenge = await auth.createChallenge(proposal.id, "wife");
const result = await auth.submitResponse({
proposalId: proposal.id,
principalId: "wife",
credentialId: "demo-credential",
response: "CONSENT",
challenge: challenge.challenge,
proof: "demo-proof",
});
if (result.resolution) {
const token = await auth.issueResolutionToken(result.resolution.id);
const verified = await auth.verifyResolutionToken(token, {
audience: "payments-api",
payload: { amount: 2500, currency: "USD", destination: "shared-savings" },
consume: true,
});
if (verified.valid) console.log("Proposal is authorized", verified.claims);
}The credential provider in this example is deliberately a test double. Real deployments should use a plugin that validates WebAuthn, OIDC, Ed25519, secp256k1, or another documented credential protocol.
Quorum Auth separates three responsibilities:
| Responsibility | Component |
|---|---|
| Prove who responded | Credential provider |
| Decide whether responses are sufficient | Decision policy |
| Perform the real-world action | Application or execution adapter |
This lets the same engine support a two-person consent flow, a team deployment approval, a community vote, or a Safe transaction gate without making any one integration mandatory.
thresholdPolicy() implements m-of-n approval using distinct non-observer participants. consentPolicy() requires every participant with the CONSENT_REQUIRED role to submit CONSENT and rejects the proposal when a required participant submits REJECT or OBJECT.
Custom policies implement the DecisionPolicy interface. Credential integrations implement CredentialProvider. Persistence integrations implement QuorumAdapter.
Every response is bound to the proposal ID, purpose, policy version, payload hash, participant-set hash, audience, challenge, and expiry. Challenges are single-use within a QuorumAuth instance. Resolution tokens are HMAC-signed, audience-bound, payload-bound, expiration-limited, and optionally consumed once through durable adapter storage.
Applications must use consume: true for irreversible operations and should also enforce an idempotency key at the final execution boundary. A valid Quorum Auth token is authorization evidence; it is not a substitute for business authorization, transaction idempotency, or on-chain enforcement.
npm install
npm test
npm run buildSee CONTRIBUTING.md before opening a pull request.
MIT. See LICENSE.