feat: (A-514) add API key authentication for admin RPC endpoint#20411
feat: (A-514) add API key authentication for admin RPC endpoint#20411danielntmd merged 1 commit intomerge-train/spartanfrom
Conversation
0160760 to
b139ba8
Compare
Compile (Noir contracts)TypeScript validationAction required: Please fix the docs examples or update them to match the current API. cc @AztecProtocol/devrel |
Flakey Tests🤖 says: This CI run detected 1 tests that failed, but were tolerated due to a .test_patterns.yml entry. |
alexghr
left a comment
There was a problem hiding this comment.
A couple of issues around function use that needs to be replaced with counterparts from fundation.
I like the idea but we need to support setting the API key/hash at boot rather than only allowing an opt out.
| export function sha256HexHash(input: string): string { | ||
| return createHash('sha256').update(input).digest('hex'); | ||
| } |
There was a problem hiding this comment.
We should use the sha256 implementation that we have in foundation.
There was a problem hiding this comment.
If we use the output of this fn to create a buffer then we can skip the extra Buffer.from(sha256HexHash(apiKey), 'hex') by calling digest() without an encoding (which would return a buffer directly)
| export function sha256HexHash(input: string): string { | |
| return createHash('sha256').update(input).digest('hex'); | |
| } | |
| export function sha256HexHash(input: string): Buffer { | |
| return createHash('sha256').update(input).digest(); | |
| } |
There was a problem hiding this comment.
returns buffer now
| } | ||
|
|
||
| const providedHashBuf = Buffer.from(sha256HexHash(providedKey), 'hex'); | ||
| if (expectedHashBuf.length !== providedHashBuf.length || !timingSafeEqual(expectedHashBuf, providedHashBuf)) { |
There was a problem hiding this comment.
sha256 always returns a 32 byte digest so checking for length differences is a no-op (aside: short-circuiting here defeats the purpose of using timingSafeEqual)
| }); | ||
| }); | ||
|
|
||
| describe('sha256HexHash', () => { |
There was a problem hiding this comment.
I think we can remove these tests once we switch to the sha256 implementation from foundation.
|
|
||
| it('logs a warning about auth being disabled', async () => { | ||
| await resolveAdminApiKey({ noAdminApiKey: true }, log); | ||
| expect(log.calls.warn.some(m => m.includes('DISABLED'))).toBe(true); |
There was a problem hiding this comment.
I'd rather we didn't test logging, it's too brittle
| const hashFilePath = join(tempDir!, 'admin', 'api_key_hash'); | ||
| const stat = await fs.stat(hashFilePath); | ||
| // 0o600 = owner read/write only (numeric mode 384) | ||
| expect(stat.mode & 0o777).toBe(0o600); |
There was a problem hiding this comment.
Wouldn't it be enough to check stat.mode === 0o600? I don't see why we need to go through the extra step.
There was a problem hiding this comment.
0o777 strips the stat mode's upper file bits,
| {{- if .Values.node.noAdminApiKey }} | ||
| - name: AZTEC_NO_ADMIN_API_KEY | ||
| value: "true" | ||
| {{- end }} |
There was a problem hiding this comment.
I think we ought to allow setting the expected hash via env vars. This will allow generating the API key ahead of time and storing it in a K8s secret (or in an external secret manager) for consumption by both the server and clients
There was a problem hiding this comment.
wired another var for consumption
| * @returns The raw key (hex string) and its SHA-256 hex hash. | ||
| */ | ||
| function generateApiKey(): { rawKey: string; hash: string } { | ||
| const rawKey = randomBytes(32).toString('hex'); |
There was a problem hiding this comment.
We should use the random source from foundation
There was a problem hiding this comment.
now using the foundation's randomBytes
Introduces auto-generated API key authentication for the admin JSON-RPC endpoint (for when docker maps NAT to the outside and general security). Key design decisions: - Keys are always auto-generated (operators cannot supply their own) to prevent weak key usage. - The raw key is displayed once at startup via stdout; only the SHA-256 hash is persisted to `<dataDirectory>/admin/api_key_hash`. - Supports both `x-api-key` and `Authorization: Bearer <key>` headers. - Health check endpoint (`GET /status`) is excluded from auth for k8s liveness/readiness probes. Modes of operation: - Persistent mode (with `--data-directory`): key hash is persisted and reused across restarts. - Opt-out: `--no-admin-api-key` / `AZTEC_NO_ADMIN_API_KEY=true` disables auth entirely. - Reset: `--reset-admin-api-key` / `AZTEC_RESET_ADMIN_API_KEY=true` forces regeneration of the key. Deployments: - Admin API key auth is disabled by default in Helm charts for now (`noAdminApiKey: true` in aztec-node base chart). Set to `false` in production values to enable. - E2E tests and Spartan deployments use no admin API key. Files added: - `api_key_auth.ts` — Koa middleware + SHA-256 hashing utility - `admin_api_key_store.ts` — key resolution, generation, and persistence - Unit, integration, and middleware tests Files modified: - `aztec_start_action.ts` — wires up middleware and displays key at startup - `aztec_start_options.ts` — adds `--no-admin-api-key` and `--reset-admin-api-key` flags - `safe_json_rpc_client.ts` — supports passing API key header from clients - `aztec-node-admin.ts` — `createAztecNodeAdminClient` now accepts an optional `apiKey` parameter that is sent as a header - Helm charts and env_var.ts updated accordingly
b139ba8 to
ff4cf99
Compare
BEGIN_COMMIT_OVERRIDE fix: stringify all bigints in pino-logger (#20303) chore: ensure consistent HA DB timestamps (#20398) chore: log L1 trace errors once in debug (#20380) test(archiver): add missing reorg and prune unit tests (#20441) feat(ci.aztec-labs.com): CI cost and metrics tracking (#20100) refactor(ethereum): cleaner initialization for tx delayer in l1txutils (#20319) chore(validator): blob upload tests (#20463) chore: move TXE ports out of Linux ephemeral range (#20475) fix(node): sync ws before simulating public calls (#20499) fix(ethereum): check timeout before consuming nonce in L1TxUtils (#20501) chore(e2e): reenable block building test (#20504) refactor(sequencer): rename block-level metrics to checkpoint-level (#20505) feat(archiver): return L2 block data to avoid fetching full block (#20503) chore(mbps): clean up TODOs for multiple blocks per slot (#20502) feat(archiver): add l2 tips cache (#20510) chore(e2e): toggle mbps in e2e tests (#20315) fix: set PXE sync chain tip to proposed for scenario bot (#20530) feat: Metrics added to the transaction pool (#20477) fix(ci): preserve both attempt logs when retrying flaky tests (#20439) feat: automatically stop node from signalling (#20416) refactor: add getCheckpointsDataForEpoch and enrich CheckpointData (#20467) refactor: make prover-node a subsystem of aztec-node (#20393) feat: worker thread wallet (#20557) chore: fix deployments (#20558) feat: suspend sentinel during escape hatch (#20471) fix: async blob (#20559) chore: vendor web3signer (#20570) fix: Fix checkpoint invalidation test (#20579) feat: World state history length is now defined in checkpoints (#20566) fix: async world state cleanups (#20578) chore: merge next into merge-train/spartan (#20582) chore: better agent utilisation in proving test (#20562) feat: (A-302) add reloadKeystore admin RPC endpoint (#20325) feat: (A-451) error codes for RPC calls (#20560) feat: (A-514) add API key authentication for admin RPC endpoint (#20411) fix: increase waitForTx timeout in epochs_invalidate_block test (#20603) chore: update block proposal/checkpoint proposal panel (#20584) fix: async dispose() lint rule (#20587) fix(p2p): fix compress option in file store and enable for tx uploads (#20605) chore: fixes for chaos mesh experiments (#20606) feat(p2p): add download metrics to file store tx source (#20601) chore: update skill to correct path and add changelog docs for new endpoints and error codes (#20607) chore: deflake epoch_mbps (#20609) END_COMMIT_OVERRIDE
Introduces auto-generated API key authentication for the admin JSON-RPC endpoint (for when docker maps NAT to the outside and general security). Key design decisions: - Keys are always auto-generated (operators cannot supply their own) to prevent weak key usage. - The raw key is displayed once at startup via stdout; only the SHA-256 hash is persisted to `<dataDirectory>/admin/api_key_hash`. - Supports both `x-api-key` and `Authorization: Bearer <key>` headers. - Health check endpoint (`GET /status`) is excluded from auth for k8s liveness/readiness probes. Modes of operation: - Persistent mode (with `--data-directory`): key hash is persisted and reused across restarts. - Opt-out: `--no-admin-api-key` / `AZTEC_NO_ADMIN_API_KEY=true` disables auth entirely. - Reset: `--reset-admin-api-key` / `AZTEC_RESET_ADMIN_API_KEY=true` forces regeneration of the key. Deployments: - Admin API key auth is disabled by default in Helm charts for now (`noAdminApiKey: true` in aztec-node base chart). Set to `false` in production values to enable. - E2E tests and Spartan deployments use no admin API key. Files added: - `api_key_auth.ts` — Koa middleware + SHA-256 hashing utility - `admin_api_key_store.ts` — key resolution, generation, and persistence - Unit, integration, and middleware tests Files modified: - `aztec_start_action.ts` — wires up middleware and displays key at startup - `aztec_start_options.ts` — adds `--no-admin-api-key` and `--reset-admin-api-key` flags - `safe_json_rpc_client.ts` — supports passing API key header from clients - `aztec-node-admin.ts` — `createAztecNodeAdminClient` now accepts an optional `apiKey` parameter that is sent as a header - Helm charts and env_var.ts updated accordingly
Pending Aztec Packages v4 release --- ## [4.0.1](v4.0.0...v4.0.1) (2026-02-26) ### � BREAKING CHANGES * Bump l2 gas per note hash ([#20862](#20862)) * update vks * update da gas ([#20611](#20611)) * change max private log size to 16 fields ([#20515](#20515)) * pairing points audit ([#20456](#20456)) * include_by_timestamp -> expiration_timestamp ([#20536](#20536)) ### Features * (A-302) add reloadKeystore admin RPC endpoint ([#20325](#20325)) ([639368d](639368d)) * (A-451) error codes for RPC calls ([#20560](#20560)) ([639368d](639368d)) * (A-514) add API key authentication for admin RPC endpoint ([#20411](#20411)) ([639368d](639368d)) * add `aztec profile` command with gate count profiling ([#20695](#20695)) ([83ea202](83ea202)) * add API key authentication for admin RPC endpoint ([ff4cf99](ff4cf99)) * add aztec profile flamegraph command ([#20741](#20741)) ([83ea202](83ea202)) * add support for signed integers on contract functions ([#20784](#20784)) ([fdd0d0d](fdd0d0d)) * adding mempool transactions ([#20679](#20679)) ([43caf7c](43caf7c)) * alpha payload ([#20865](#20865)) ([7a09c3c](7a09c3c)) * **archiver:** add l2 tips cache ([#20510](#20510)) ([639368d](639368d)) * **archiver:** return L2 block data to avoid fetching full block ([#20503](#20503)) ([639368d](639368d)) * automatically stop node from signalling ([#20416](#20416)) ([639368d](639368d)) * avoid redundant serial zeroing in polynomial allocation ([#20670](#20670)) ([bb844d4](bb844d4)) * call syncImmediate without block number during chain prune ([#20717](#20717)) ([43caf7c](43caf7c)) * check calldata against emitted hashes ([#20486](#20486)) ([43caf7c](43caf7c)) * **ci.aztec-labs.com:** CI cost and metrics tracking ([#20100](#20100)) ([639368d](639368d)) * disabling peer scoring for block proposals topic ([#20577](#20577)) ([6414d9b](6414d9b)) * dynamically adjust missing txs set ([#20300](#20300)) ([dedf440](dedf440)) * Error codes for RPC calls ([43ed6a9](43ed6a9)) * expose blockheader getters ([#20790](#20790)) ([fdd0d0d](fdd0d0d)) * Metrics added to the transaction pool ([#20477](#20477)) ([639368d](639368d)) * notify slack on merge train PR merge ([#20614](#20614)) ([dbbeddc](dbbeddc)) * **p2p:** add download metrics to file store tx source ([#20601](#20601)) ([639368d](639368d)) * printing out public contract function debug logs in a tx ([#20749](#20749)) ([83ea202](83ea202)) * Re-instate the function optionally to delete all transactions in an epoch prune ([#20602](#20602)) ([dedf440](dedf440)) * reduced hashing ([#20676](#20676)) ([bf3191c](bf3191c)) * run low priority eviction rule on chain_pruned ([#20687](#20687)) ([43caf7c](43caf7c)) * suspend sentinel during escape hatch ([#20471](#20471)) ([639368d](639368d)) * tcmalloc enabled in docker images ([#20644](#20644)) ([b87c8ae](b87c8ae)) * trim attestations to the minimum required length ([#20591](#20591)) ([43caf7c](43caf7c)) * use native crypto to compute p2p message ID ([#20846](#20846)) ([fdd0d0d](fdd0d0d)) * Validate num txs in block proposals ([#20850](#20850)) ([f3f5438](f3f5438)) * worker thread wallet ([#20557](#20557)) ([639368d](639368d)) * World state history length is now defined in checkpoints ([#20566](#20566)) ([639368d](639368d)) ### Bug Fixes * (A-575) prevent checkpoint event spam in L2BlockStream on restart ([#20791](#20791)) ([fdd0d0d](fdd0d0d)) * `DelayedPublicMutable` not relying on the guarantee of increasing timestamps ([#20244](#20244)) ([a178034](a178034)) * allow compiling mixed (contract + noir script) aztec project ([#20428](#20428)) ([83ea202](83ea202)) * **archiver:** enforce checkpoint boundary on rollbackTo ([#20908](#20908)) ([f3f5438](f3f5438)) * async blob ([#20559](#20559)) ([639368d](639368d)) * async dispose() lint rule ([#20587](#20587)) ([639368d](639368d)) * async world state cleanups ([#20578](#20578)) ([639368d](639368d)) * attribute for L1 fee analysis for full blocks ([#20548](#20548)) ([63131de](63131de)) * **avm:** alu gadget fuzzer serialisation ([#19115](#19115)) ([50e778a](50e778a)) * **aztec-up:** install noir-profiler alongside nargo ([#20896](#20896)) ([f3f5438](f3f5438)) * charge 3.6M for epoch verification ([#20765](#20765)) ([fdd0d0d](fdd0d0d)) * **ci:** insufficient parallelism in merge-queue-heavy ([#20613](#20613)) ([5bfbd67](5bfbd67)) * **ci:** preserve both attempt logs when retrying flaky tests ([#20439](#20439)) ([639368d](639368d)) * default pp handling ([#20516](#20516)) ([f9431cd](f9431cd)) * do not ignore test artifacts ([#20574](#20574)) ([402f438](402f438)) * docs examples lockfile ([#20453](#20453)) ([4bf9ddd](4bf9ddd)) * escape hatch snapshots ([#20363](#20363)) ([e4712cd](e4712cd)) * **ethereum:** check timeout before consuming nonce in L1TxUtils ([#20501](#20501)) ([639368d](639368d)) * **ethereum:** remove viem NonceManager to fix nonce gap after failed sends ([#20819](#20819)) ([fdd0d0d](fdd0d0d)) * evicted transactions could reappear after a node restart ([#20773](#20773)) ([fdd0d0d](fdd0d0d)) * Fix checkpoint invalidation test ([#20579](#20579)) ([639368d](639368d)) * Fix the epoch long proving test ([#20617](#20617)) ([6414d9b](6414d9b)) * flag stripping error ([#20655](#20655)) ([b87c8ae](b87c8ae)) * getVotes return empty instead of stale data ([#20756](#20756)) ([fdd0d0d](fdd0d0d)) * hodgepodge of small things ([#20720](#20720)) ([43caf7c](43caf7c)) * increase waitForTx timeout in epochs_invalidate_block test ([#20603](#20603)) ([639368d](639368d)) * limit number of threads when verifying server-side proofs ([#20818](#20818)) ([fdd0d0d](fdd0d0d)) * min expiration timestamp instead of assert ([#20554](#20554)) ([fa29717](fa29717)) * misc minor contract fixes ([#20423](#20423)) ([3a13674](3a13674)) * **node:** sync ws before simulating public calls ([#20499](#20499)) ([639368d](639368d)) * **p2p:** fix compress option in file store and enable for tx uploads ([#20605](#20605)) ([639368d](639368d)) * **p2p:** wait for GossipSub mesh formation before sending txs in e2e tests ([#20626](#20626)) ([fdd0d0d](fdd0d0d)) * pass log level to AVM simulator ([#20762](#20762)) ([fdd0d0d](fdd0d0d)) * pxe native prover log level ([#20724](#20724)) ([fdd0d0d](fdd0d0d)) * Reduce tx hash conversions inside tx pool ([#20829](#20829)) ([fdd0d0d](fdd0d0d)) * respecting MAX_RPC_LEN limit in getAllLogsByTags ([#20543](#20543)) ([c2475bd](c2475bd)) * separate rejected and aborted proving jobs ([#20777](#20777)) ([fdd0d0d](fdd0d0d)) * Set Aztec slot duration as a multiple of the Ethereum slot duration ([#20608](#20608)) ([dedf440](dedf440)) * set PXE sync chain tip to proposed for scenario bot ([#20530](#20530)) ([639368d](639368d)) * skip default pp in sol aggregation ([#20521](#20521)) ([f9431cd](f9431cd)) * stringify all bigints in pino-logger ([#20303](#20303)) ([639368d](639368d)) * sync world state before forking in simulatePublicCalls ([#20544](#20544)) ([f3420e0](f3420e0)) * track last seen nonce in case of stale fallback L1 RPC node ([#20855](#20855)) ([83ea202](83ea202)) * **txe:** committing after txs ([#20714](#20714)) ([83ea202](83ea202)) * underflow in snapshot synch ([#20780](#20780)) ([fdd0d0d](fdd0d0d)) * Use async poseidon ([#20826](#20826)) ([fdd0d0d](fdd0d0d)) * use ci3_labels_to_env.sh for ci-external label ([#20597](#20597)) ([3efb1d9](3efb1d9)) * write pointers for environ_get and environ_sizes_get functions ([#20902](#20902)) ([f3f5438](f3f5438)) * yolo debugging tweaks ([0a9d6e0](0a9d6e0)) * yolo some fd cleanup, maybe stop hangs ([43d292c](43d292c)) ### Miscellaneous * include_by_timestamp -> expiration_timestamp ([#20536](#20536)) ([44a33a1](44a33a1)) * update vks ([4d653dd](4d653dd)) ### Documentation * document RevertCodeEnum phases and add 120-char line width rule ([#20751](#20751)) ([83ea202](83ea202)) * fix avm docs - l2 gas is not the same as mana ([#20565](#20565)) ([50e778a](50e778a)) * minor clarification ([#20788](#20788)) ([fdd0d0d](fdd0d0d)) * simulator readme typos ([#19701](#19701)) ([50e778a](50e778a)) * some tail circuit doc comments ([#20449](#20449)) ([fd509a3](fd509a3)) This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
Pending Aztec Packages v4 release --- ## [4.0.1](v4.0.0...v4.0.1) (2026-02-26) ### � BREAKING CHANGES * Bump l2 gas per note hash ([#20862](#20862)) * update vks * update da gas ([#20611](#20611)) * change max private log size to 16 fields ([#20515](#20515)) * pairing points audit ([#20456](#20456)) * include_by_timestamp -> expiration_timestamp ([#20536](#20536)) ### Features * (A-302) add reloadKeystore admin RPC endpoint ([#20325](#20325)) ([639368d](639368d)) * (A-451) error codes for RPC calls ([#20560](#20560)) ([639368d](639368d)) * (A-514) add API key authentication for admin RPC endpoint ([#20411](#20411)) ([639368d](639368d)) * add `aztec profile` command with gate count profiling ([#20695](#20695)) ([83ea202](83ea202)) * add API key authentication for admin RPC endpoint ([ff4cf99](ff4cf99)) * add aztec profile flamegraph command ([#20741](#20741)) ([83ea202](83ea202)) * add support for signed integers on contract functions ([#20784](#20784)) ([fdd0d0d](fdd0d0d)) * adding mempool transactions ([#20679](#20679)) ([43caf7c](43caf7c)) * alpha payload ([#20865](#20865)) ([7a09c3c](7a09c3c)) * **archiver:** add l2 tips cache ([#20510](#20510)) ([639368d](639368d)) * **archiver:** return L2 block data to avoid fetching full block ([#20503](#20503)) ([639368d](639368d)) * automatically stop node from signalling ([#20416](#20416)) ([639368d](639368d)) * avoid redundant serial zeroing in polynomial allocation ([#20670](#20670)) ([bb844d4](bb844d4)) * call syncImmediate without block number during chain prune ([#20717](#20717)) ([43caf7c](43caf7c)) * check calldata against emitted hashes ([#20486](#20486)) ([43caf7c](43caf7c)) * **ci.aztec-labs.com:** CI cost and metrics tracking ([#20100](#20100)) ([639368d](639368d)) * disabling peer scoring for block proposals topic ([#20577](#20577)) ([6414d9b](6414d9b)) * dynamically adjust missing txs set ([#20300](#20300)) ([dedf440](dedf440)) * Error codes for RPC calls ([43ed6a9](43ed6a9)) * expose blockheader getters ([#20790](#20790)) ([fdd0d0d](fdd0d0d)) * Metrics added to the transaction pool ([#20477](#20477)) ([639368d](639368d)) * notify slack on merge train PR merge ([#20614](#20614)) ([dbbeddc](dbbeddc)) * **p2p:** add download metrics to file store tx source ([#20601](#20601)) ([639368d](639368d)) * printing out public contract function debug logs in a tx ([#20749](#20749)) ([83ea202](83ea202)) * Re-instate the function optionally to delete all transactions in an epoch prune ([#20602](#20602)) ([dedf440](dedf440)) * reduced hashing ([#20676](#20676)) ([bf3191c](bf3191c)) * run low priority eviction rule on chain_pruned ([#20687](#20687)) ([43caf7c](43caf7c)) * suspend sentinel during escape hatch ([#20471](#20471)) ([639368d](639368d)) * tcmalloc enabled in docker images ([#20644](#20644)) ([b87c8ae](b87c8ae)) * trim attestations to the minimum required length ([#20591](#20591)) ([43caf7c](43caf7c)) * use native crypto to compute p2p message ID ([#20846](#20846)) ([fdd0d0d](fdd0d0d)) * Validate num txs in block proposals ([#20850](#20850)) ([f3f5438](f3f5438)) * worker thread wallet ([#20557](#20557)) ([639368d](639368d)) * World state history length is now defined in checkpoints ([#20566](#20566)) ([639368d](639368d)) ### Bug Fixes * (A-575) prevent checkpoint event spam in L2BlockStream on restart ([#20791](#20791)) ([fdd0d0d](fdd0d0d)) * `DelayedPublicMutable` not relying on the guarantee of increasing timestamps ([#20244](#20244)) ([a178034](a178034)) * allow compiling mixed (contract + noir script) aztec project ([#20428](#20428)) ([83ea202](83ea202)) * **archiver:** enforce checkpoint boundary on rollbackTo ([#20908](#20908)) ([f3f5438](f3f5438)) * async blob ([#20559](#20559)) ([639368d](639368d)) * async dispose() lint rule ([#20587](#20587)) ([639368d](639368d)) * async world state cleanups ([#20578](#20578)) ([639368d](639368d)) * attribute for L1 fee analysis for full blocks ([#20548](#20548)) ([63131de](63131de)) * **avm:** alu gadget fuzzer serialisation ([#19115](#19115)) ([50e778a](50e778a)) * **aztec-up:** install noir-profiler alongside nargo ([#20896](#20896)) ([f3f5438](f3f5438)) * charge 3.6M for epoch verification ([#20765](#20765)) ([fdd0d0d](fdd0d0d)) * **ci:** insufficient parallelism in merge-queue-heavy ([#20613](#20613)) ([5bfbd67](5bfbd67)) * **ci:** preserve both attempt logs when retrying flaky tests ([#20439](#20439)) ([639368d](639368d)) * default pp handling ([#20516](#20516)) ([f9431cd](f9431cd)) * do not ignore test artifacts ([#20574](#20574)) ([402f438](402f438)) * docs examples lockfile ([#20453](#20453)) ([4bf9ddd](4bf9ddd)) * escape hatch snapshots ([#20363](#20363)) ([e4712cd](e4712cd)) * **ethereum:** check timeout before consuming nonce in L1TxUtils ([#20501](#20501)) ([639368d](639368d)) * **ethereum:** remove viem NonceManager to fix nonce gap after failed sends ([#20819](#20819)) ([fdd0d0d](fdd0d0d)) * evicted transactions could reappear after a node restart ([#20773](#20773)) ([fdd0d0d](fdd0d0d)) * Fix checkpoint invalidation test ([#20579](#20579)) ([639368d](639368d)) * Fix the epoch long proving test ([#20617](#20617)) ([6414d9b](6414d9b)) * flag stripping error ([#20655](#20655)) ([b87c8ae](b87c8ae)) * getVotes return empty instead of stale data ([#20756](#20756)) ([fdd0d0d](fdd0d0d)) * hodgepodge of small things ([#20720](#20720)) ([43caf7c](43caf7c)) * increase waitForTx timeout in epochs_invalidate_block test ([#20603](#20603)) ([639368d](639368d)) * limit number of threads when verifying server-side proofs ([#20818](#20818)) ([fdd0d0d](fdd0d0d)) * min expiration timestamp instead of assert ([#20554](#20554)) ([fa29717](fa29717)) * misc minor contract fixes ([#20423](#20423)) ([3a13674](3a13674)) * **node:** sync ws before simulating public calls ([#20499](#20499)) ([639368d](639368d)) * **p2p:** fix compress option in file store and enable for tx uploads ([#20605](#20605)) ([639368d](639368d)) * **p2p:** wait for GossipSub mesh formation before sending txs in e2e tests ([#20626](#20626)) ([fdd0d0d](fdd0d0d)) * pass log level to AVM simulator ([#20762](#20762)) ([fdd0d0d](fdd0d0d)) * pxe native prover log level ([#20724](#20724)) ([fdd0d0d](fdd0d0d)) * Reduce tx hash conversions inside tx pool ([#20829](#20829)) ([fdd0d0d](fdd0d0d)) * respecting MAX_RPC_LEN limit in getAllLogsByTags ([#20543](#20543)) ([c2475bd](c2475bd)) * separate rejected and aborted proving jobs ([#20777](#20777)) ([fdd0d0d](fdd0d0d)) * Set Aztec slot duration as a multiple of the Ethereum slot duration ([#20608](#20608)) ([dedf440](dedf440)) * set PXE sync chain tip to proposed for scenario bot ([#20530](#20530)) ([639368d](639368d)) * skip default pp in sol aggregation ([#20521](#20521)) ([f9431cd](f9431cd)) * stringify all bigints in pino-logger ([#20303](#20303)) ([639368d](639368d)) * sync world state before forking in simulatePublicCalls ([#20544](#20544)) ([f3420e0](f3420e0)) * track last seen nonce in case of stale fallback L1 RPC node ([#20855](#20855)) ([83ea202](83ea202)) * **txe:** committing after txs ([#20714](#20714)) ([83ea202](83ea202)) * underflow in snapshot synch ([#20780](#20780)) ([fdd0d0d](fdd0d0d)) * Use async poseidon ([#20826](#20826)) ([fdd0d0d](fdd0d0d)) * use ci3_labels_to_env.sh for ci-external label ([#20597](#20597)) ([3efb1d9](3efb1d9)) * write pointers for environ_get and environ_sizes_get functions ([#20902](#20902)) ([f3f5438](f3f5438)) * yolo debugging tweaks ([0a9d6e0](0a9d6e0)) * yolo some fd cleanup, maybe stop hangs ([43d292c](43d292c)) ### Miscellaneous * include_by_timestamp -> expiration_timestamp ([#20536](#20536)) ([44a33a1](44a33a1)) * update vks ([4d653dd](4d653dd)) ### Documentation * document RevertCodeEnum phases and add 120-char line width rule ([#20751](#20751)) ([83ea202](83ea202)) * fix avm docs - l2 gas is not the same as mana ([#20565](#20565)) ([50e778a](50e778a)) * minor clarification ([#20788](#20788)) ([fdd0d0d](fdd0d0d)) * simulator readme typos ([#19701](#19701)) ([50e778a](50e778a)) * some tail circuit doc comments ([#20449](#20449)) ([fd509a3](fd509a3)) This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
Pending Aztec Packages v4 release --- ## [4.0.1](v4.0.0...v4.0.1) (2026-02-26) ### � BREAKING CHANGES * Bump l2 gas per note hash ([#20862](#20862)) * update vks * update da gas ([#20611](#20611)) * change max private log size to 16 fields ([#20515](#20515)) * pairing points audit ([#20456](#20456)) * include_by_timestamp -> expiration_timestamp ([#20536](#20536)) ### Features * (A-302) add reloadKeystore admin RPC endpoint ([#20325](#20325)) ([639368d](639368d)) * (A-451) error codes for RPC calls ([#20560](#20560)) ([639368d](639368d)) * (A-514) add API key authentication for admin RPC endpoint ([#20411](#20411)) ([639368d](639368d)) * add `aztec profile` command with gate count profiling ([#20695](#20695)) ([83ea202](83ea202)) * add API key authentication for admin RPC endpoint ([ff4cf99](ff4cf99)) * add aztec profile flamegraph command ([#20741](#20741)) ([83ea202](83ea202)) * add support for signed integers on contract functions ([#20784](#20784)) ([fdd0d0d](fdd0d0d)) * adding mempool transactions ([#20679](#20679)) ([43caf7c](43caf7c)) * alpha payload ([#20865](#20865)) ([7a09c3c](7a09c3c)) * **archiver:** add l2 tips cache ([#20510](#20510)) ([639368d](639368d)) * **archiver:** return L2 block data to avoid fetching full block ([#20503](#20503)) ([639368d](639368d)) * automatically stop node from signalling ([#20416](#20416)) ([639368d](639368d)) * avoid redundant serial zeroing in polynomial allocation ([#20670](#20670)) ([bb844d4](bb844d4)) * call syncImmediate without block number during chain prune ([#20717](#20717)) ([43caf7c](43caf7c)) * check calldata against emitted hashes ([#20486](#20486)) ([43caf7c](43caf7c)) * **ci.aztec-labs.com:** CI cost and metrics tracking ([#20100](#20100)) ([639368d](639368d)) * disabling peer scoring for block proposals topic ([#20577](#20577)) ([6414d9b](6414d9b)) * dynamically adjust missing txs set ([#20300](#20300)) ([dedf440](dedf440)) * Error codes for RPC calls ([43ed6a9](43ed6a9)) * expose blockheader getters ([#20790](#20790)) ([fdd0d0d](fdd0d0d)) * Metrics added to the transaction pool ([#20477](#20477)) ([639368d](639368d)) * notify slack on merge train PR merge ([#20614](#20614)) ([dbbeddc](dbbeddc)) * **p2p:** add download metrics to file store tx source ([#20601](#20601)) ([639368d](639368d)) * printing out public contract function debug logs in a tx ([#20749](#20749)) ([83ea202](83ea202)) * Re-instate the function optionally to delete all transactions in an epoch prune ([#20602](#20602)) ([dedf440](dedf440)) * reduced hashing ([#20676](#20676)) ([bf3191c](bf3191c)) * run low priority eviction rule on chain_pruned ([#20687](#20687)) ([43caf7c](43caf7c)) * suspend sentinel during escape hatch ([#20471](#20471)) ([639368d](639368d)) * tcmalloc enabled in docker images ([#20644](#20644)) ([b87c8ae](b87c8ae)) * trim attestations to the minimum required length ([#20591](#20591)) ([43caf7c](43caf7c)) * use native crypto to compute p2p message ID ([#20846](#20846)) ([fdd0d0d](fdd0d0d)) * Validate num txs in block proposals ([#20850](#20850)) ([f3f5438](f3f5438)) * worker thread wallet ([#20557](#20557)) ([639368d](639368d)) * World state history length is now defined in checkpoints ([#20566](#20566)) ([639368d](639368d)) ### Bug Fixes * (A-575) prevent checkpoint event spam in L2BlockStream on restart ([#20791](#20791)) ([fdd0d0d](fdd0d0d)) * `DelayedPublicMutable` not relying on the guarantee of increasing timestamps ([#20244](#20244)) ([a178034](a178034)) * allow compiling mixed (contract + noir script) aztec project ([#20428](#20428)) ([83ea202](83ea202)) * **archiver:** enforce checkpoint boundary on rollbackTo ([#20908](#20908)) ([f3f5438](f3f5438)) * async blob ([#20559](#20559)) ([639368d](639368d)) * async dispose() lint rule ([#20587](#20587)) ([639368d](639368d)) * async world state cleanups ([#20578](#20578)) ([639368d](639368d)) * attribute for L1 fee analysis for full blocks ([#20548](#20548)) ([63131de](63131de)) * **avm:** alu gadget fuzzer serialisation ([#19115](#19115)) ([50e778a](50e778a)) * **aztec-up:** install noir-profiler alongside nargo ([#20896](#20896)) ([f3f5438](f3f5438)) * charge 3.6M for epoch verification ([#20765](#20765)) ([fdd0d0d](fdd0d0d)) * **ci:** insufficient parallelism in merge-queue-heavy ([#20613](#20613)) ([5bfbd67](5bfbd67)) * **ci:** preserve both attempt logs when retrying flaky tests ([#20439](#20439)) ([639368d](639368d)) * default pp handling ([#20516](#20516)) ([f9431cd](f9431cd)) * do not ignore test artifacts ([#20574](#20574)) ([402f438](402f438)) * docs examples lockfile ([#20453](#20453)) ([4bf9ddd](4bf9ddd)) * escape hatch snapshots ([#20363](#20363)) ([e4712cd](e4712cd)) * **ethereum:** check timeout before consuming nonce in L1TxUtils ([#20501](#20501)) ([639368d](639368d)) * **ethereum:** remove viem NonceManager to fix nonce gap after failed sends ([#20819](#20819)) ([fdd0d0d](fdd0d0d)) * evicted transactions could reappear after a node restart ([#20773](#20773)) ([fdd0d0d](fdd0d0d)) * Fix checkpoint invalidation test ([#20579](#20579)) ([639368d](639368d)) * Fix the epoch long proving test ([#20617](#20617)) ([6414d9b](6414d9b)) * flag stripping error ([#20655](#20655)) ([b87c8ae](b87c8ae)) * getVotes return empty instead of stale data ([#20756](#20756)) ([fdd0d0d](fdd0d0d)) * hodgepodge of small things ([#20720](#20720)) ([43caf7c](43caf7c)) * increase waitForTx timeout in epochs_invalidate_block test ([#20603](#20603)) ([639368d](639368d)) * limit number of threads when verifying server-side proofs ([#20818](#20818)) ([fdd0d0d](fdd0d0d)) * min expiration timestamp instead of assert ([#20554](#20554)) ([fa29717](fa29717)) * misc minor contract fixes ([#20423](#20423)) ([3a13674](3a13674)) * **node:** sync ws before simulating public calls ([#20499](#20499)) ([639368d](639368d)) * **p2p:** fix compress option in file store and enable for tx uploads ([#20605](#20605)) ([639368d](639368d)) * **p2p:** wait for GossipSub mesh formation before sending txs in e2e tests ([#20626](#20626)) ([fdd0d0d](fdd0d0d)) * pass log level to AVM simulator ([#20762](#20762)) ([fdd0d0d](fdd0d0d)) * pxe native prover log level ([#20724](#20724)) ([fdd0d0d](fdd0d0d)) * Reduce tx hash conversions inside tx pool ([#20829](#20829)) ([fdd0d0d](fdd0d0d)) * respecting MAX_RPC_LEN limit in getAllLogsByTags ([#20543](#20543)) ([c2475bd](c2475bd)) * separate rejected and aborted proving jobs ([#20777](#20777)) ([fdd0d0d](fdd0d0d)) * Set Aztec slot duration as a multiple of the Ethereum slot duration ([#20608](#20608)) ([dedf440](dedf440)) * set PXE sync chain tip to proposed for scenario bot ([#20530](#20530)) ([639368d](639368d)) * skip default pp in sol aggregation ([#20521](#20521)) ([f9431cd](f9431cd)) * stringify all bigints in pino-logger ([#20303](#20303)) ([639368d](639368d)) * sync world state before forking in simulatePublicCalls ([#20544](#20544)) ([f3420e0](f3420e0)) * track last seen nonce in case of stale fallback L1 RPC node ([#20855](#20855)) ([83ea202](83ea202)) * **txe:** committing after txs ([#20714](#20714)) ([83ea202](83ea202)) * underflow in snapshot synch ([#20780](#20780)) ([fdd0d0d](fdd0d0d)) * Use async poseidon ([#20826](#20826)) ([fdd0d0d](fdd0d0d)) * use ci3_labels_to_env.sh for ci-external label ([#20597](#20597)) ([3efb1d9](3efb1d9)) * write pointers for environ_get and environ_sizes_get functions ([#20902](#20902)) ([f3f5438](f3f5438)) * yolo debugging tweaks ([0a9d6e0](0a9d6e0)) * yolo some fd cleanup, maybe stop hangs ([43d292c](43d292c)) ### Miscellaneous * include_by_timestamp -> expiration_timestamp ([#20536](#20536)) ([44a33a1](44a33a1)) * update vks ([4d653dd](4d653dd)) ### Documentation * document RevertCodeEnum phases and add 120-char line width rule ([#20751](#20751)) ([83ea202](83ea202)) * fix avm docs - l2 gas is not the same as mana ([#20565](#20565)) ([50e778a](50e778a)) * minor clarification ([#20788](#20788)) ([fdd0d0d](fdd0d0d)) * simulator readme typos ([#19701](#19701)) ([50e778a](50e778a)) * some tail circuit doc comments ([#20449](#20449)) ([fd509a3](fd509a3)) This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
Pending Aztec Packages v4 release --- ## [4.0.1](v4.0.0...v4.0.1) (2026-02-26) ### � BREAKING CHANGES * Bump l2 gas per note hash ([#20862](#20862)) * update vks * update da gas ([#20611](#20611)) * change max private log size to 16 fields ([#20515](#20515)) * pairing points audit ([#20456](#20456)) * include_by_timestamp -> expiration_timestamp ([#20536](#20536)) ### Features * (A-302) add reloadKeystore admin RPC endpoint ([#20325](#20325)) ([639368d](639368d)) * (A-451) error codes for RPC calls ([#20560](#20560)) ([639368d](639368d)) * (A-514) add API key authentication for admin RPC endpoint ([#20411](#20411)) ([639368d](639368d)) * add `aztec profile` command with gate count profiling ([#20695](#20695)) ([83ea202](83ea202)) * add API key authentication for admin RPC endpoint ([ff4cf99](ff4cf99)) * add aztec profile flamegraph command ([#20741](#20741)) ([83ea202](83ea202)) * add support for signed integers on contract functions ([#20784](#20784)) ([fdd0d0d](fdd0d0d)) * adding mempool transactions ([#20679](#20679)) ([43caf7c](43caf7c)) * alpha payload ([#20865](#20865)) ([7a09c3c](7a09c3c)) * **archiver:** add l2 tips cache ([#20510](#20510)) ([639368d](639368d)) * **archiver:** return L2 block data to avoid fetching full block ([#20503](#20503)) ([639368d](639368d)) * automatically stop node from signalling ([#20416](#20416)) ([639368d](639368d)) * avoid redundant serial zeroing in polynomial allocation ([#20670](#20670)) ([bb844d4](bb844d4)) * call syncImmediate without block number during chain prune ([#20717](#20717)) ([43caf7c](43caf7c)) * check calldata against emitted hashes ([#20486](#20486)) ([43caf7c](43caf7c)) * **ci.aztec-labs.com:** CI cost and metrics tracking ([#20100](#20100)) ([639368d](639368d)) * disabling peer scoring for block proposals topic ([#20577](#20577)) ([6414d9b](6414d9b)) * dynamically adjust missing txs set ([#20300](#20300)) ([dedf440](dedf440)) * Error codes for RPC calls ([43ed6a9](43ed6a9)) * expose blockheader getters ([#20790](#20790)) ([fdd0d0d](fdd0d0d)) * Metrics added to the transaction pool ([#20477](#20477)) ([639368d](639368d)) * notify slack on merge train PR merge ([#20614](#20614)) ([dbbeddc](dbbeddc)) * **p2p:** add download metrics to file store tx source ([#20601](#20601)) ([639368d](639368d)) * printing out public contract function debug logs in a tx ([#20749](#20749)) ([83ea202](83ea202)) * Re-instate the function optionally to delete all transactions in an epoch prune ([#20602](#20602)) ([dedf440](dedf440)) * reduced hashing ([#20676](#20676)) ([bf3191c](bf3191c)) * run low priority eviction rule on chain_pruned ([#20687](#20687)) ([43caf7c](43caf7c)) * suspend sentinel during escape hatch ([#20471](#20471)) ([639368d](639368d)) * tcmalloc enabled in docker images ([#20644](#20644)) ([b87c8ae](b87c8ae)) * trim attestations to the minimum required length ([#20591](#20591)) ([43caf7c](43caf7c)) * use native crypto to compute p2p message ID ([#20846](#20846)) ([fdd0d0d](fdd0d0d)) * Validate num txs in block proposals ([#20850](#20850)) ([f3f5438](f3f5438)) * worker thread wallet ([#20557](#20557)) ([639368d](639368d)) * World state history length is now defined in checkpoints ([#20566](#20566)) ([639368d](639368d)) ### Bug Fixes * (A-575) prevent checkpoint event spam in L2BlockStream on restart ([#20791](#20791)) ([fdd0d0d](fdd0d0d)) * `DelayedPublicMutable` not relying on the guarantee of increasing timestamps ([#20244](#20244)) ([a178034](a178034)) * allow compiling mixed (contract + noir script) aztec project ([#20428](#20428)) ([83ea202](83ea202)) * **archiver:** enforce checkpoint boundary on rollbackTo ([#20908](#20908)) ([f3f5438](f3f5438)) * async blob ([#20559](#20559)) ([639368d](639368d)) * async dispose() lint rule ([#20587](#20587)) ([639368d](639368d)) * async world state cleanups ([#20578](#20578)) ([639368d](639368d)) * attribute for L1 fee analysis for full blocks ([#20548](#20548)) ([63131de](63131de)) * **avm:** alu gadget fuzzer serialisation ([#19115](#19115)) ([50e778a](50e778a)) * **aztec-up:** install noir-profiler alongside nargo ([#20896](#20896)) ([f3f5438](f3f5438)) * charge 3.6M for epoch verification ([#20765](#20765)) ([fdd0d0d](fdd0d0d)) * **ci:** insufficient parallelism in merge-queue-heavy ([#20613](#20613)) ([5bfbd67](5bfbd67)) * **ci:** preserve both attempt logs when retrying flaky tests ([#20439](#20439)) ([639368d](639368d)) * default pp handling ([#20516](#20516)) ([f9431cd](f9431cd)) * do not ignore test artifacts ([#20574](#20574)) ([402f438](402f438)) * docs examples lockfile ([#20453](#20453)) ([4bf9ddd](4bf9ddd)) * escape hatch snapshots ([#20363](#20363)) ([e4712cd](e4712cd)) * **ethereum:** check timeout before consuming nonce in L1TxUtils ([#20501](#20501)) ([639368d](639368d)) * **ethereum:** remove viem NonceManager to fix nonce gap after failed sends ([#20819](#20819)) ([fdd0d0d](fdd0d0d)) * evicted transactions could reappear after a node restart ([#20773](#20773)) ([fdd0d0d](fdd0d0d)) * Fix checkpoint invalidation test ([#20579](#20579)) ([639368d](639368d)) * Fix the epoch long proving test ([#20617](#20617)) ([6414d9b](6414d9b)) * flag stripping error ([#20655](#20655)) ([b87c8ae](b87c8ae)) * getVotes return empty instead of stale data ([#20756](#20756)) ([fdd0d0d](fdd0d0d)) * hodgepodge of small things ([#20720](#20720)) ([43caf7c](43caf7c)) * increase waitForTx timeout in epochs_invalidate_block test ([#20603](#20603)) ([639368d](639368d)) * limit number of threads when verifying server-side proofs ([#20818](#20818)) ([fdd0d0d](fdd0d0d)) * min expiration timestamp instead of assert ([#20554](#20554)) ([fa29717](fa29717)) * misc minor contract fixes ([#20423](#20423)) ([3a13674](3a13674)) * **node:** sync ws before simulating public calls ([#20499](#20499)) ([639368d](639368d)) * **p2p:** fix compress option in file store and enable for tx uploads ([#20605](#20605)) ([639368d](639368d)) * **p2p:** wait for GossipSub mesh formation before sending txs in e2e tests ([#20626](#20626)) ([fdd0d0d](fdd0d0d)) * pass log level to AVM simulator ([#20762](#20762)) ([fdd0d0d](fdd0d0d)) * pxe native prover log level ([#20724](#20724)) ([fdd0d0d](fdd0d0d)) * Reduce tx hash conversions inside tx pool ([#20829](#20829)) ([fdd0d0d](fdd0d0d)) * respecting MAX_RPC_LEN limit in getAllLogsByTags ([#20543](#20543)) ([c2475bd](c2475bd)) * separate rejected and aborted proving jobs ([#20777](#20777)) ([fdd0d0d](fdd0d0d)) * Set Aztec slot duration as a multiple of the Ethereum slot duration ([#20608](#20608)) ([dedf440](dedf440)) * set PXE sync chain tip to proposed for scenario bot ([#20530](#20530)) ([639368d](639368d)) * skip default pp in sol aggregation ([#20521](#20521)) ([f9431cd](f9431cd)) * stringify all bigints in pino-logger ([#20303](#20303)) ([639368d](639368d)) * sync world state before forking in simulatePublicCalls ([#20544](#20544)) ([f3420e0](f3420e0)) * track last seen nonce in case of stale fallback L1 RPC node ([#20855](#20855)) ([83ea202](83ea202)) * **txe:** committing after txs ([#20714](#20714)) ([83ea202](83ea202)) * underflow in snapshot synch ([#20780](#20780)) ([fdd0d0d](fdd0d0d)) * Use async poseidon ([#20826](#20826)) ([fdd0d0d](fdd0d0d)) * use ci3_labels_to_env.sh for ci-external label ([#20597](#20597)) ([3efb1d9](3efb1d9)) * write pointers for environ_get and environ_sizes_get functions ([#20902](#20902)) ([f3f5438](f3f5438)) * yolo debugging tweaks ([0a9d6e0](0a9d6e0)) * yolo some fd cleanup, maybe stop hangs ([43d292c](43d292c)) ### Miscellaneous * include_by_timestamp -> expiration_timestamp ([#20536](#20536)) ([44a33a1](44a33a1)) * update vks ([4d653dd](4d653dd)) ### Documentation * document RevertCodeEnum phases and add 120-char line width rule ([#20751](#20751)) ([83ea202](83ea202)) * fix avm docs - l2 gas is not the same as mana ([#20565](#20565)) ([50e778a](50e778a)) * minor clarification ([#20788](#20788)) ([fdd0d0d](fdd0d0d)) * simulator readme typos ([#19701](#19701)) ([50e778a](50e778a)) * some tail circuit doc comments ([#20449](#20449)) ([fd509a3](fd509a3)) This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
Introduces auto-generated API key authentication for the admin JSON-RPC endpoint (for when docker maps NAT to the outside and general security).
Key design decisions:
<dataDirectory>/admin/api_key_hash.x-api-keyandAuthorization: Bearer <key>headers.GET /status) is excluded from auth for k8s liveness/readiness probes.Modes of operation:
--data-directory): key hash is persisted and reused across restarts.--no-admin-api-key/AZTEC_NO_ADMIN_API_KEY=truedisables auth entirely.--reset-admin-api-key/AZTEC_RESET_ADMIN_API_KEY=trueforces regeneration of the key.Deployments:
noAdminApiKey: truein aztec-node base chart). Set tofalsein production values to enable.Files added:
api_key_auth.ts— Koa middleware + SHA-256 hashing utilityadmin_api_key_store.ts— key resolution, generation, and persistenceFiles modified:
aztec_start_action.ts— wires up middleware and displays key at startupaztec_start_options.ts— adds--no-admin-api-keyand--reset-admin-api-keyflagssafe_json_rpc_client.ts— supports passing API key header from clientsaztec-node-admin.ts—createAztecNodeAdminClientnow accepts an optionalapiKeyparameter that is sent as a header