# How the mpcium Authorizer-Based Authorization System Works: Configuration, Verification, and CLI Workflow

> Learn how the mpcium authorizer-based authorization system secures messages with cryptographic signatures and Ed25519/P-256 verification. Understand configuration, CLI workflow, and key management.

- Repository: [Fystack Labs/mpcium](https://github.com/fystack/mpcium)
- Tags: deep-dive
- Published: 2026-03-02

---

**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`](https://github.com/fystack/mpcium/blob/main/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`](https://github.com/fystack/mpcium/blob/main/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:

```yaml
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`](https://github.com/fystack/mpcium/blob/main/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:

1. **`*.authorizer.identity.json`** – Contains the authorizer ID, algorithm, and hex-encoded public key for distribution to node operators.
2. **`*.authorizer.key.age`** – The private key encrypted with age (when using the `--encrypt` flag).

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`](https://github.com/fystack/mpcium/blob/main/pkg/identity/identity.go).

### The Dual-Verification Pipeline

The entry point `AuthorizeInitiatorMessage` (lines 79-118) performs two distinct checks:

1. **Initiator signature verification** – `VerifyInitiatorMessage` (lines 67-77) validates the message originator using their configured algorithm.
2. **Authorizer gating** – Only proceeds if `authConfig.Enabled` is 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`](https://github.com/fystack/mpcium/blob/main/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.Verify` with the 32-byte public key.
- **P-256**: Uses `encryption.VerifyP256Signature` with 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:

```go
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 `AuthorizationConfig` struct within [`pkg/identity/identity.go`](https://github.com/fystack/mpcium/blob/main/pkg/identity/identity.go) (lines 81-85), enabling mandatory and optional authorizer lists through `required_authorizers`.
- The CLI tool `mpcium-cli generate-authorizer` creates 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`](https://github.com/fystack/mpcium/blob/main/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`](https://github.com/fystack/mpcium/blob/main/cmd/mpcium-cli/generate-authorizer.go) (lines 140-199) allows secure storage of signing material without exposing plaintext private keys.