Authorization Process
The Wallet backend is responsible for collecting approvals among the quorum members and submits them together to MPC Nodes. Each approver authenticates the same request with their credential.
End-to-end process
MPC Nodes do not wait while approvals are collected. Collection completes in
the Wallet backend before the network request begins.
Collect a signing quorum
This section presents Quorum approval over the signature (DSG) request. Initiator builds the request, and two approvers must sign-off over it.
1. Freeze the signing payload
import {
SignRequestBuilder,
SignSetupOpts,
} from '@silencelaboratories/walletprovider-sdk';
const message = new SignRequestBuilder()
.setRequest(crypto.randomUUID(), 'Approve payroll', 'EIP191')
.build();
const payload = new SignSetupOpts({
t: 2,
key_id: keyId,
signAlg: 'secp256k1',
message,
});
All approvers must authenticate the same unchanged payload. Changing it requires collecting new signatures.
2. Authenticate on each client
import {
UserSignatures,
type AuthModule,
} from '@silencelaboratories/walletprovider-sdk';
async function authenticateSign(authModule: AuthModule) {
const signatures = await new UserSignatures(authModule, 'v2').build(
'signgen',
payload,
);
if (!signatures.default) throw new Error('Authentication produced no signature');
return signatures.default;
}
// Each call runs on the corresponding credential holder's machine.
const initiatorSignature = await authenticateSign(initiatorAuth);
const adminASignature = await authenticateSign(adminAAuth);
const adminBSignature = await authenticateSign(adminBAuth);
3. Submit the complete bundle
import { HttpClient } from '@silencelaboratories/walletprovider-sdk';
const http = new HttpClient('https://wallet-backend.example');
const signatures = await http.post('/v2/rest/signgen', {
payload,
userSignatures: {
default: initiatorSignature,
approvals: [adminASignature, adminBSignature],
grantees: [],
},
});
The initiator contributes a vote when its credential is a member of
the matching Rule.approval.
Authorize policy management
Policy updates and deletion use the current
management_approval
group.
| Action | default | Counted approvals | Additional signature |
|---|---|---|---|
| Update conditions only | Authorization root | Current management members | None |
| Add or increase a member's approval capability | Authorization root | Current management members | One matching grantees[] entry per affected credential |
| Remove a member | Authorization root | Current management members | None |
| Delete policy | Authorization root | Current management members | None |
All participants authenticate the same epoch-bound request.
expectedAuthorizationEpoch is the key's
current authorization epoch; the
nodes reject the request if it does not match the epoch they hold. Policy deletion example:
import {
DeletePolicyRequest,
UserSignatures,
type AuthModule,
} from '@silencelaboratories/walletprovider-sdk';
const payload = new DeletePolicyRequest({
keyId,
expectedAuthorizationEpoch: currentAuthorizationEpoch,
});
async function authenticateDelete(authModule: AuthModule) {
const signatures = await new UserSignatures(authModule, 'v2').build(
'deletePolicy',
payload,
);
if (!signatures.default) throw new Error('Authentication produced no signature');
return signatures.default;
}
const rootSignature = await authenticateDelete(rootAuth);
const adminSignature = await authenticateDelete(adminAuth);
await http.post('/v2/rest/deletePolicy', {
payload,
userSignatures: {
default: rootSignature,
approvals: [adminSignature],
grantees: [],
},
});
A successful deletion advances the key's authorization epoch, removes the policy, and removes every policy-derived approval grant. The authorization root remains.
Counting and rejection rules
Each of the participating MPC Nodes applies these rules on its own, against
its own copy of the key's current grants and policy.
- Every signature must authenticate the same request.
- A credential can appear at most once in
approvalsand once ingrantees. The initiator's own credential cannot be repeated in either array. - The initiator and each entry in
approvalscontribute one approval each, but only where that credential is a member of the approval group for this action. - An entry in
granteesproves that its holder consents to a new or increased capability. It never counts as an approval.
The Wallet backend can take as long as it needs to collect the signatures.
MPC Nodes see only the finished bundle, and the decision is theirs, not the
backend's.