How the mpcium Authorizer-Based Authorization System Works: Configuration, Verification, and CLI Workflow
The mpcium authorizer-based authorization system mandates cryptographic signatures from designated authorizers on every initiator-type message, verifying them against cached public keys using Ed25519 or P-256 algorithms before processing key generation, signing, or resharing requests.
The mpcium framework implements a robust authorization system that adds an independent security layer to threshold MPC operations. This authorizer-based model requires external approval for sensitive actions through cryptographic signatures stored in cachedAuthorizerKeys and validated via AuthorizeInitiatorMessage. According to the fystack/mpcium source code, the implementation spans three core areas: configuration management in pkg/identity/identity.go, identity generation via CLI utilities, and deterministic message verification flows.
Configuring Authorizers in mpcium
The authorization behavior is controlled by the AuthorizationConfig struct defined in pkg/identity/identity.go (lines 81-85). This configuration specifies whether the system is active, which authorizer IDs are mandatory, and the public key material for each verifier.
Authorization Configuration Structure
A typical YAML configuration lives under the top-level authorization key:
authorization:
enabled: true # globally enables authorizer checks
required_authorizers:
- auth1 # IDs that must sign every message
- auth2
authorizer_public_keys:
auth1:
public_key: "ab12cd..." # hex-encoded key
algorithm: "ed25519"
auth2:
public_key: "04fe..." # hex-encoded P-256 key
algorithm: "p256"
The authorization.enabled boolean acts as the global gate; when false, AuthorizeInitiatorMessage skips all checks (lines 79-84). The required_authorizers slice enforces that specific entities must sign every initiator message, while authorizer_public_keys maps IDs to their cryptographic material.
Loading and Caching Public Keys
When the store initializes via NewFileStore, the loadAuthorizationConfig function (lines 48-82) parses the configuration block. It validates each hex-encoded public key and converts them to Go crypto primitives—either ed25519.PublicKey or *ecdsa.PublicKey—storing the results in cachedAuthorizerKeys (lines 59-78). This cache eliminates repeated parsing during hot-path message verification.
Generating Authorizer Identities
New authorizers are created using the mpcium-cli generate-authorizer command implemented in cmd/mpcium-cli/generate-authorizer.go.
CLI Key Generation Workflow
The command validates the authorizer name and algorithm selection (Ed25519 or P-256) at lines 33-68. It then generates the key pair using encryption.GenerateEd25519Keys or encryption.GenerateP256Keys (lines 107-115), ensuring cryptographically secure randomness for the private material.
Output Files and Encryption
The utility produces two artifacts:
*.authorizer.identity.json– Contains the authorizer ID, algorithm, and hex-encoded public key for distribution to node operators.*.authorizer.key.age– The private key encrypted with age (when using the--encryptflag).
This separation allows operators to commit public identity files to version control while keeping private keys encrypted at rest (lines 140-199). The JSON entry is then copied into the node's authorizer_public_keys configuration map.
Verifying Initiator Messages
When a node receives an initiator message—such as GenerateKeyMessage, SignTxMessage, or ResharingMessage—the store executes a multi-stage verification pipeline defined in pkg/identity/identity.go.
The Dual-Verification Pipeline
The entry point AuthorizeInitiatorMessage (lines 79-118) performs two distinct checks:
- Initiator signature verification –
VerifyInitiatorMessage(lines 67-77) validates the message originator using their configured algorithm. - Authorizer gating – Only proceeds if
authConfig.Enabledis true.
Required Authorizer Enforcement
If required_authorizers is non-empty, the function iterates through the list and ensures each ID appears in the message's AuthorizerSignatures slice (lines 85-98). Missing signatures return an immediate error identifying the deficient authorizer.
Deterministic Payload Construction
Before signature verification, the system builds a canonical signing payload using types.ComposeAuthorizerRaw in pkg/types/initiator_msg.go (lines 29-46). This function creates a deterministic JSON blob containing:
- The initiator's ID
- The initiator's raw payload
- The initiator's signature
Authorizers sign this composed raw data rather than the message directly, ensuring consistent verification across distributed nodes.
Algorithm-Specific Signature Verification
The verifyAuthorizerSignature helper (lines 20-44) looks up the cached public key for each authorizer and dispatches to the appropriate verification routine:
- Ed25519: Uses
ed25519.Verifywith the 32-byte public key. - P-256: Uses
encryption.VerifyP256Signaturewith the uncompressed or compressed curve point.
Errors are wrapped with the authorizer ID to simplify debugging failed verifications.
Implementing Authorizer Signing
Authorizers must produce signatures over the deterministic payload. A Go implementation follows this pattern:
func signAsAuthorizer(
authorizerPrivKey []byte, // hex-decoded private key
authorizerAlg types.EventInitiatorKeyType,
msg types.InitiatorMessage,
) (types.AuthorizerSignature, error) {
// Build the canonical authorizer payload
raw, err := types.ComposeAuthorizerRaw(msg)
if err != nil {
return types.AuthorizerSignature{}, err
}
// Sign with the correct algorithm
var sig []byte
switch authorizerAlg {
case types.EventInitiatorKeyTypeEd25519:
sig = ed25519.Sign(authorizerPrivKey, raw)
case types.EventInitiatorKeyTypeP256:
sig, err = encryption.SignWithP256(authorizerPrivKey, raw)
if err != nil {
return types.AuthorizerSignature{}, err
}
default:
return types.AuthorizerSignature{}, fmt.Errorf("unsupported algorithm %s", authorizerAlg)
}
return types.AuthorizerSignature{
AuthorizerID: "auth1", // the configured ID string
Signature: sig,
}, nil
}
The resulting AuthorizerSignature struct is appended to the message's AuthorizerSignatures field before transmission to mpcium nodes.
Summary
- The mpcium authorizer-based authorization system supports Ed25519 and P-256 cryptographic algorithms for signature verification.
- Configuration is defined in the
AuthorizationConfigstruct withinpkg/identity/identity.go(lines 81-85), enabling mandatory and optional authorizer lists throughrequired_authorizers. - The CLI tool
mpcium-cli generate-authorizercreates identity files with optional age encryption for secure private key storage. - Message verification follows a strict sequence: initiator signature validation, enabled-flag gating, required-authorizer presence checks, and deterministic payload verification via
ComposeAuthorizerRaw. - Authorizers cryptographically attest to a canonical payload generated by
types.ComposeAuthorizerRaw(lines 29-46), ensuring consistent replay across the distributed system.
Frequently Asked Questions
What cryptographic algorithms does mpcium support for authorizer signatures?
mpcium supports Ed25519 and P-256 (secp256r1) algorithms. The system validates these during configuration loading in loadAuthorizationConfig and uses algorithm-specific verification paths in verifyAuthorizerSignature (lines 20-44) to dispatch to either ed25519.Verify or encryption.VerifyP256Signature.
How do I add a new authorizer to an existing mpcium deployment?
Generate a new identity using mpcium-cli generate-authorizer with the --name and --algorithm flags, then copy the public key from the resulting *.authorizer.identity.json file into the authorizer_public_keys map within the node's authorization configuration. The loadAuthorizationConfig function (lines 48-82) automatically caches the new key at startup.
What happens if a required authorizer signature is missing?
The AuthorizeInitiatorMessage function returns an error indicating which required authorizer ID is absent from the message's AuthorizerSignatures slice. This check occurs at lines 85-98 in pkg/identity/identity.go, halting processing until all mandatory signatures are present.
Can authorizer private keys be stored encrypted?
Yes. The CLI's --encrypt flag triggers age encryption for the private key output file (.authorizer.key.age), while the public identity file remains unencrypted for configuration distribution. This implementation in cmd/mpcium-cli/generate-authorizer.go (lines 140-199) allows secure storage of signing material without exposing plaintext private keys.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →