Skip to main content
Version: v3.0.0-nightly.20251204

Creating Sequencer Keystores

Overview

Keystores are configuration files that store the cryptographic keys and addresses your sequencer node needs to operate on the Aztec network. This guide shows you how to create keystores using the Aztec CLI's validator-keys commands.

A keystore contains:

  • Attester keys: Your sequencer's identity (Ethereum and BLS keys for signing proposals and attestations)
  • Publisher keys: Keys used to submit blocks to L1 (requires ETH for gas)
  • Fee recipient: Aztec address for L2 transaction fees (currently not used)
  • Coinbase address: Ethereum address receiving L1 block rewards (optional, defaults to attester address)

Prerequisites

Before creating keystores, ensure you have:

  • Basic understanding of Ethereum addresses and private keys
  • Access to an Ethereum L1 RPC endpoint
  • Foundry toolkit installed (for creating publisher addresses)

Installing the Aztec CLI

First, install the Aztec CLI using the official installer:

bash -i <(curl -s https://install.aztec.network)

Then install the correct version for the current network:

aztec-up 2.1.7

Verify your CLI installation:

aztec --version

This approach creates multiple sequencer identities (validators) that share a single publisher address for submitting transactions to L1. This is the recommended configuration for production deployments.

Step 1: Create Publisher Address and Set RPC Endpoint

First, set your Ethereum L1 RPC endpoint:

export ETH_RPC=https://ethereum-rpc.publicnode.com

Or use your preferred Ethereum RPC provider (Infura, Alchemy, etc.).

Then generate a separate address for publishing transactions to L1 using the Foundry toolkit:

cast wallet new-mnemonic --words 24

Example output:

Successfully generated a new mnemonic.
Phrase:
word1 word2 word3 word4 word5 word6 word7 word8 word9 word10 word11 word12 word13 word14 word15 word16 word17 word18 word19 word20 word21 word22 word23 word24

Accounts:
- Account 0:
Address: 0xE434A95e816991E66bF7052955FD699aEf8a286b
Private key: 0x7988a4a7...79f058a0
Critical: Save Your Publisher Mnemonic

The 24-word mnemonic is the only way to recover your publisher private key. Store it securely offline (not on the server running the node).

Save from the output:

  • ✅ The 24-word mnemonic (for recovery)
  • ✅ The private key (you'll use this in the next step)
  • ✅ The address (you'll fund this with ETH)

Step 2: Generate Your Keystores with Publisher

Generate 5 validators with the publisher private key from Step 1:

aztec validator-keys new \
--fee-recipient 0x0000000000000000000000000000000000000000000000000000000000000000 \
--staker-output \
--gse-address 0xa92ecFD0E70c9cd5E5cd76c50Af0F7Da93567a4f \
--l1-rpc-urls $ETH_RPC \
--count 5 \
--publishers 0x7988a4a779f058a0

Replace 0x7988a4a779f058a0 with your actual publisher private key from Step 1.

What this command does:

  • Generates a new mnemonic for your validator keys (save this securely!)
  • Creates 5 sequencer identities (validators) with Ethereum and BLS keys
  • Configures all validators to use the same publisher address for L1 submissions
  • Generates public keystore data for the staking dashboard
  • Saves files to ~/.aztec/keystore/

Example output:

No mnemonic provided, generating new one...
Using new mnemonic:

absent city nephew garment million badge front text memory grape two lizard

Wrote validator keystore to /Users/your-name/.aztec/keystore/key1.json
Wrote staker output for 5 validator(s) to /Users/your-name/.aztec/keystore/key1_staker_output.json

acc1:
attester:
eth: 0x8E76a8B8D66E0A56E241F2768fD2ad4eba07E565
bls: 0x29eaf46e4699e33a1abe7300258567c624a7304a2134e31aa2609437f281d81d
publisher:
- 0x7988a4a779f058a0
acc2:
attester:
eth: 0x2037b472537a4246B1A7325f327028EF450ba0Ef
bls: 0x8d7eb7d9436ac6cb9b8f1c211673ea228c7f438882e6438b2caefca753df28e8
publisher:
- 0x7988a4a779f058a0
acc3:
attester:
eth: 0x0c14593f7465DeDbb86d68982374BB05F4C60386
bls: 0xad1cccf512d2f180238af795831344445f7ac47e2d623f3dac854e93e5b1e76d
publisher:
- 0x7988a4a779f058a0
acc4:
attester:
eth: 0x4D213928988f0123f6b3B4A377F856812F08E831
bls: 0xa90f5889dddd4cd6bc5a28db5e0db60d3cbf5147eb6e82b313024b2d0634110e
publisher:
- 0x7988a4a779f058a0
acc5:
attester:
eth: 0x29f147Da38d5F66bB84e791969b365c796829c92
bls: 0x0d683001c2ce866e322f0c7509f087a909508787d125336931aa9168d2a1f95b
publisher:
- 0x7988a4a779f058a0

Note: The publisher value shown is the private key (truncated in this example). All validators share the same publisher private key.

Staker outputs:
[
{
"attester": "0x8E76a8B8D66E0A56E241F2768fD2ad4eba07E565",
"publicKeyG1": { "x": "0x...", "y": "0x..." },
"publicKeyG2": { "x0": "0x...", "x1": "0x...", "y0": "0x...", "y1": "0x..." },
"proofOfPossession": { "x": "0x...", "y": "0x..." }
},
... (4 more validators)
]
Critical: Save Both Mnemonics

You now have two separate mnemonics to secure:

  1. Validator mnemonic (shown above, 12 words) - Regenerates your attester keys
  2. Publisher mnemonic (from Step 1, 24 words) - Regenerates your publisher key

Both must be stored securely offline. Losing either mnemonic means losing access to those keys.

Files created:

  • ~/.aztec/keystore/key1.json - Private keystore with all 5 validators and publisher configured
  • ~/.aztec/keystore/key1_staker_output.json - Public keystore for staking dashboard

Step 3: Fund the Publisher Address

Your publisher address needs ETH to pay for L1 gas when submitting proposals.

Funding requirement: At least 0.3 ETH for 5 validators (rule of thumb: 0.1 ETH per validator)

Transfer ETH to the publisher address from Step 1. You can check the balance with:

cast balance 0xE434A95e816991E66bF7052955FD699aEf8a286b --rpc-url $ETH_RPC

Replace the address with your actual publisher address.

Monitor Publisher Balance

Set up monitoring to alert when the publisher balance falls below 0.5 ETH to prevent failed block publications.

Step 4: Upload Keystore to Your Node

Now you're ready to spin up your sequencer node!

Upload the private keystore to your server:

The key1.json file contains your private keys and must be uploaded to your sequencer node.

For standard server deployments:

# Upload to your server's keystore directory
scp ~/.aztec/keystore/key1.json user@your-server:/path/to/aztec-sequencer/keys/keystore.json

For dAppNode deployments:

  • Upload key1.json to the dAppNode keystore folder
  • Rename it to keystore.json
Keep the Public Keystore Local

Keep key1_staker_output.json on your local machine - you'll need it for registration on the staking dashboard. Do not upload this to your server.

Step 5: Start Your Node

Start your sequencer node following the Sequencer Management guide.

When your node starts successfully, you'll see output similar to:

Started validator with addresses: 0x8E76a8B8D66E0A56E241F2768fD2ad4eba07E565, 0x2037b472537a4246B1A7325f327028EF450ba0Ef, 0x0c14593f7465DeDbb86d68982374BB05F4C60386, 0x4D213928988f0123f6b3B4A377F856812F08E831, 0x29f147Da38d5F66bB84e791969b365c796829c92

These are your validator attester addresses - they match the addresses shown when you generated your keys.

Step 6: Register Your Validators

Use the public keystore (key1_staker_output.json) to register your validators on the staking dashboard. See Registering a Sequencer for details.


Quick Setup Summary

By following the recommended setup, you've accomplished:

Generated a dedicated publisher address with its own 24-word mnemonic ✅ Created 5 validator identities with a separate 12-word mnemonic ✅ Configured all validators to use the shared publisher for L1 transactions ✅ Funded the publisher with at least 0.3 ETH for gas costs ✅ Uploaded the private keystore (key1.json) to your sequencer node ✅ Started your node and verified validator addresses in the output ✅ Ready to register using the public keystore (key1_staker_output.json)

Two mnemonics to keep secure:

  1. Publisher mnemonic (24 words) - Recovers publisher private key
  2. Validator mnemonic (12 words) - Recovers all 5 validator attester keys

Alternative: Single Validator Setup

For testing or simpler setups, you can create a single validator that uses its attester key as the publisher.

Basic Single Validator

aztec validator-keys new \
--fee-recipient 0x0000000000000000000000000000000000000000000000000000000000000000 \
--staker-output \
--gse-address 0xa92ecFD0E70c9cd5E5cd76c50Af0F7Da93567a4f \
--l1-rpc-urls $ETH_RPC

This creates:

  • One validator with attester keys
  • No separate publisher (attester key used for publishing)
  • Private keystore at ~/.aztec/keystore/keyN.json
  • Public keystore at ~/.aztec/keystore/keyN_staker_output.json
When to Use Single Validator

Use single validator setup for:

  • Testing and development
  • Simple deployments with one sequencer identity
  • When you don't need to isolate attester and publisher keys

Understanding Keystore Structure

Private Keystore Format

The private keystore (key1.json) contains sensitive private keys:

{
"schemaVersion": 1,
"validators": [
{
"attester": {
"eth": "0x...", // Ethereum private key - sequencer identifier
"bls": "0x..." // BLS private key - signs proposals and attestations
},
"publisher": ["0x..."], // Publisher private key(s) for L1 submissions
"feeRecipient": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x..." // Optional: custom address for L1 rewards
}
]
}

Field descriptions:

  • attester.eth: Derives the address that serves as your sequencer's unique identifier
  • attester.bls: Signs proposals and attestations, used for staking operations
  • publisher: Array of private keys for submitting signed messages to L1 (pays gas)
  • feeRecipient: L2 fee recipient (not currently used, set to all zeros)
  • coinbase: L1 block reward recipient (optional, defaults to attester address)

Public Keystore Format

The public keystore (key1_staker_output.json) contains only public information safe to share:

[
{
"attester": "0xYOUR_ATTESTER_ADDRESS",
"publicKeyG1": {
"x": "0x...",
"y": "0x..."
},
"publicKeyG2": {
"x0": "0x...",
"x1": "0x...",
"y0": "0x...",
"y1": "0x..."
},
"proofOfPossession": {
"x": "0x...",
"y": "0x..."
}
}
]

This file is used for registration on the staking dashboard and contains no private keys.

Advanced Options

Providing Your Own Mnemonic

For deterministic key generation or to recreate keys from an existing mnemonic:

aztec validator-keys new \
--fee-recipient 0x0000000000000000000000000000000000000000000000000000000000000000 \
--staker-output \
--gse-address 0xa92ecFD0E70c9cd5E5cd76c50Af0F7Da93567a4f \
--l1-rpc-urls $ETH_RPC \
--mnemonic "your existing twelve word mnemonic phrase here" \
--count 5 \
--publishers 0x7988a4a779f058a0

This regenerates the same validators if you've used this mnemonic before, or creates new ones at the next derivation indices.

Custom Output Location

Specify custom directory and filename:

aztec validator-keys new \
--fee-recipient 0x0000000000000000000000000000000000000000000000000000000000000000 \
--staker-output \
--gse-address 0xa92ecFD0E70c9cd5E5cd76c50Af0F7Da93567a4f \
--l1-rpc-urls $ETH_RPC \
--count 5 \
--publishers 0x7988a4a779f058a0 \
--data-dir ~/my-sequencer/keys \
--file sequencer1.json

This creates keystores at:

  • ~/my-sequencer/keys/sequencer1.json (private keystore)
  • ~/my-sequencer/keys/sequencer1_staker_output.json (public keystore)

Default behavior (if you don't specify --data-dir or --file):

  • Directory: ~/.aztec/keystore/
  • Filename: key1.json, key2.json, etc. (auto-increments)

Verifying Your Keystore

Verify the keystore is valid JSON:

cat ~/.aztec/keystore/key1.json | jq .

Check validator count:

jq '.validators | length' ~/.aztec/keystore/key1.json

Verify BLS keys are present:

jq '.validators[0].attester.bls' ~/.aztec/keystore/key1.json

Extract attester addresses:

# Get attester ETH private key (to derive address)
jq -r '.validators[0].attester.eth' ~/.aztec/keystore/key1.json

Common Issues

Missing fee-recipient Flag

Error message:

error: required option '--fee-recipient <address>' not specified

Solution: The CLI requires the --fee-recipient flag. Use the zero address:

--fee-recipient 0x0000000000000000000000000000000000000000000000000000000000000000

RPC Connection Issues

Error message:

Error: HTTP request failed

Solutions:

  • Verify $ETH_RPC is set correctly: echo $ETH_RPC
  • Test RPC connectivity: cast block-number --rpc-url $ETH_RPC
  • Try a different RPC provider if the current one is rate-limited

Permission Denied

Error message:

Error: permission denied

Solution: Ensure you have write permissions for the target directory:

mkdir -p ~/.aztec/keystore
chmod 755 ~/.aztec/keystore

Invalid Keystore JSON

Error: Node fails to load keystore

Solutions:

  • Validate JSON syntax: jq . ~/.aztec/keystore/key1.json
  • Ensure all required fields are present
  • Check that publisher is an array: ["0x..."] not "0x..."
  • Verify private keys are 64-character hex strings (with or without 0x prefix)

Legacy BLS Key Derivation (2.1.4 Users)

Issue: Need to regenerate keys that were created with CLI version 2.1.4 or earlier

Version 2.1.5 changed the BLS key derivation path, which means keys generated from the same mnemonic produce different results. This affects users who:

  • Generated keys with version 2.1.4 using --count parameter
  • Used --account-index explicitly in version 2.1.4
  • Need to regenerate keys from mnemonic that are already registered in the GSE contract

The derivation path change:

  • 2.1.4: m/12381/3600/0/0/0, m/12381/3600/1/0/0, m/12381/3600/2/0/0
  • 2.1.5+: m/12381/3600/0/0/0, m/12381/3600/0/0/1, m/12381/3600/0/0/2

Solution: Use the --legacy flag

If you generated keys with version 2.1.4 and need to regenerate them from your mnemonic, use the --legacy flag:

aztec validator-keys new \
--fee-recipient 0x0000000000000000000000000000000000000000000000000000000000000000 \
--staker-output \
--gse-address 0xa92ecFD0E70c9cd5E5cd76c50Af0F7Da93567a4f \
--l1-rpc-urls $ETH_RPC \
--mnemonic "your twelve word mnemonic phrase here" \
--count 5 \
--legacy

The --legacy flag uses the 2.1.4 derivation path to reproduce your original keys.

When NOT to Use --legacy

Do NOT use the --legacy flag if:

  • You're generating keys for the first time
  • You generated keys with version 2.1.5 or later
  • You didn't use --count or --account-index in version 2.1.4

Using --legacy unnecessarily will create keys with the old derivation path that won't match your newer registrations.

Why This Matters

BLS keys are registered in the GSE (Governance Staking Escrow) contract and cannot be easily updated. If you regenerate keys with a different derivation path, they won't match what's registered on chain, and your sequencer won't be able to attest properly.

Security Best Practices

Protecting Private Keys

  1. Never commit keystores to version control

    • Add keystore.json to .gitignore
    • Store keystores outside your project directory
  2. Backup your mnemonic securely

    • Write it down offline
    • Store in a secure location (not on the server)
    • Consider using a hardware wallet or password manager
  3. Limit keystore access

    chmod 600 ~/.aztec/keystore/key1.json
  4. Separate publisher from attester

    • Use dedicated publisher keys
    • Keep attester keys offline when possible
    • Use remote signers for production

Production Deployments

For production, consider:

  • Hardware Security Modules (HSMs) for key storage
  • Remote signers to keep keys off the node
  • Encrypted keystores with password protection
  • Key management systems (HashiCorp Vault, AWS Secrets Manager)

See Key Storage Methods for advanced security patterns.

CLI Reference

validator-keys new

Create a new keystore with validators:

aztec validator-keys new [options]

Common Options:

OptionDescriptionDefault
--fee-recipient <address>L2 fee recipient (required)None
--mnemonic <phrase>12 or 24 word mnemonicAuto-generated
--count <number>Number of validators to create1
--publisher-count <number>Publishers per validator0
--staker-outputGenerate public keystore for stakingfalse
--gse-address <address>GSE contract address (required with --staker-output)None
--l1-rpc-urls <urls>L1 RPC endpoints (required with --staker-output)None
--legacyUse 2.1.4 BLS derivation path (only for regenerating old keys)false
--data-dir <path>Output directory~/.aztec/keystore
--file <name>Keystore filenamekey1.json

For the complete list:

aztec validator-keys new --help

validator-keys add

Add validators to an existing keystore:

aztec validator-keys add <keystore-path> [options]

validator-keys staker

Generate staker output from an existing keystore:

aztec validator-keys staker \
--from <keystore-path> \
--gse-address <address> \
--l1-rpc-urls <url> \
--output <output-file>

Next Steps

Now that you've created your keystores:

For Sequencer Operators

  1. Fund publisher addresses - At least 0.1 ETH per validator
  2. Set up your node - See Sequencer Management
  3. Register validators - Use the public keystore with the staking dashboard
  4. Monitor operations - Track attestations and publisher balance

Advanced Configurations

Getting Help