Skip to content

fix(agglayer): replace NoAuth with AuthNetworkAccount on bridge and faucet#2818

Merged
mmagician merged 12 commits into
nextfrom
ajl-agglayer-network-account
May 13, 2026
Merged

fix(agglayer): replace NoAuth with AuthNetworkAccount on bridge and faucet#2818
mmagician merged 12 commits into
nextfrom
ajl-agglayer-network-account

Conversation

@partylikeits1983
Copy link
Copy Markdown
Contributor

@partylikeits1983 partylikeits1983 commented Apr 22, 2026

Summary

Closes #2797.

Installs the AuthNetworkAccount auth component (added in #2817) on both the AggLayer bridge and the AggLayer faucet, with per-account whitelists of input-note script roots. This closes the forged-MINT attack surface: an attacker can no longer finalize an arbitrary transaction against the bridge and emit a bridge-authored MINT note.

Allow lists for agglayer network accounts

  • Bridge: CLAIM, B2AGG, CONFIG_AGG_BRIDGE, UPDATE_GER
  • Faucet: MINT, BURN

Stacking

This PR is the final one in the #2797 fix chain:

@partylikeits1983 partylikeits1983 changed the title fix(agglayer): replace NoAuth with NetworkAccount on bridge and faucet (fixes #2797) fix(agglayer): replace NoAuth with NetworkAccount on bridge and faucet Apr 23, 2026
@partylikeits1983 partylikeits1983 self-assigned this Apr 23, 2026
@partylikeits1983 partylikeits1983 added agglayer PRs or issues related to AggLayer bridging integration pr-from-maintainers PRs that come from internal contributors or integration partners. They should be given priority labels Apr 23, 2026
@partylikeits1983 partylikeits1983 marked this pull request as ready for review April 23, 2026 20:58
@mmagician
Copy link
Copy Markdown
Collaborator

Note: this and the supporting PR(s) should be cherry-picked into the agglayer branch after they land on next (or vice-versa) to make a follow-up to the audit simpler.

@partylikeits1983 partylikeits1983 marked this pull request as draft April 30, 2026 02:16
@PhilippGackstatter
Copy link
Copy Markdown
Contributor

I think this PR is a requirement before we can remove AccountStorageMode::Network (#2285). All standard network accounts we define (bridge + agglayer faucet, network fungible faucet) need to start using AuthNetworkAccount, so that we can identify them as network accounts via the NetworkAccountNoteAllowlist storage slot rather than the storage mode.

My understanding is this PR deals with the bridge and agglayer faucet, so the next step after this PR is to migrate the network fungible faucet (as created by create_network_fungible_faucet) and then remove the storage mode.

@partylikeits1983 partylikeits1983 changed the base branch from ajl-network-account-component to next May 8, 2026 16:09
@partylikeits1983 partylikeits1983 changed the base branch from next to ajl-network-account-component May 8, 2026 16:10
@partylikeits1983 partylikeits1983 force-pushed the ajl-agglayer-network-account branch from 4e73ef7 to 21b4307 Compare May 8, 2026 16:40
@partylikeits1983 partylikeits1983 changed the base branch from ajl-network-account-component to next May 8, 2026 16:40
@partylikeits1983 partylikeits1983 changed the title fix(agglayer): replace NoAuth with NetworkAccount on bridge and faucet fix(agglayer): replace NoAuth with AuthNetworkAccount on bridge and faucet May 8, 2026
@partylikeits1983 partylikeits1983 force-pushed the ajl-agglayer-network-account branch 2 times, most recently from 92bbfd3 to 275e441 Compare May 8, 2026 16:58
Closes #2797.

Installs the AuthNetworkAccount auth component on both the AggLayer
bridge and the AggLayer faucet, with per-account allowlists of input-note
script roots. Both accounts now reject any transaction that runs a tx
script or consumes a note whose script root is outside the allowlist,
preventing a forged-MINT path where a transaction against the bridge
could emit a bridge-authored MINT note.

Allowlists:
- Bridge: CLAIM, B2AGG, CONFIG_AGG_BRIDGE, UPDATE_GER
- Faucet: MINT, BURN

Changes:
- crates/miden-agglayer/src/lib.rs: install AuthNetworkAccount in
  create_bridge_account, create_existing_bridge_account,
  create_agglayer_faucet, create_existing_agglayer_faucet. Add helper
  functions bridge_note_allowlist() and faucet_note_allowlist(), plus a
  claim_script_root() accessor mirroring the other note wrappers.
- crates/miden-agglayer/build.rs: compute BRIDGE_CODE_COMMITMENT and
  FAUCET_CODE_COMMITMENT using AuthNetworkAccount with a placeholder
  allowlist (allowlist contents do not affect the code commitment, and
  AuthNetworkAccount rejects empty allowlists at construction time).
- crates/miden-testing/tests/agglayer/network_account_regression.rs: two
  tests against a bridge built with the production
  create_existing_bridge_account helper, covering the tx-script
  rejection and non-allowlisted-note rejection paths.
@partylikeits1983 partylikeits1983 force-pushed the ajl-agglayer-network-account branch from 275e441 to 1441d6a Compare May 8, 2026 17:26
@partylikeits1983 partylikeits1983 marked this pull request as ready for review May 8, 2026 17:31
@partylikeits1983
Copy link
Copy Markdown
Contributor Author

Rebased onto next and ported to the AuthNetworkAccount API from #2883. Will address @PhilippGackstatter's create_network_fungible_faucet migration and @mmagician's agglayer branch cherry-pick as follow-ups. Ready for review.

Copy link
Copy Markdown
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thank you! I reviewed only non-test code and left some small comments inline.

Comment thread crates/miden-agglayer/build.rs
Comment thread crates/miden-agglayer/src/lib.rs Outdated
Comment thread crates/miden-agglayer/src/lib.rs Outdated
Comment thread crates/miden-agglayer/src/lib.rs Outdated
Comment thread crates/miden-agglayer/src/lib.rs Outdated
partylikeits1983 added a commit that referenced this pull request May 11, 2026
- AggLayerBridge::allowed_notes() / AggLayerFaucet::allowed_notes() replace
  the free bridge_note_allowlist() / faucet_note_allowlist() helpers.
- .with_auth_component(...) is installed inside the bridge and faucet
  builders, so the four create_* wrappers stop duplicating it.
- ClaimNote unit struct with ClaimNote::script() / ClaimNote::script_root()
  replaces the free claim_script() / claim_script_root() in lib.rs,
  matching the B2AggNote / ConfigAggBridgeNote / UpdateGerNote shape.
- build.rs comment: the placeholder allowlist lives in storage, not code,
  so it does not affect the computed code commitment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- AggLayerBridge::allowed_notes() / AggLayerFaucet::allowed_notes() replace
  the free bridge_note_allowlist() / faucet_note_allowlist() helpers.
- .with_auth_component(...) is installed inside the bridge and faucet
  builders, so the four create_* wrappers stop duplicating it.
- ClaimNote unit struct with ClaimNote::script() / ClaimNote::script_root()
  replaces the free claim_script() / claim_script_root() in lib.rs,
  matching the B2AggNote / ConfigAggBridgeNote / UpdateGerNote shape.
- build.rs comment: the placeholder allowlist lives in storage, not code,
  so it does not affect the computed code commitment.
@partylikeits1983 partylikeits1983 force-pushed the ajl-agglayer-network-account branch from 776b2c5 to 81e2f66 Compare May 11, 2026 22:42
@partylikeits1983
Copy link
Copy Markdown
Contributor Author

Force-pushed 776b2c5a -> 81e2f66c to update the commit message.

Comment thread crates/miden-agglayer/src/claim_note.rs
Comment thread crates/miden-agglayer/src/claim_note.rs
Comment thread crates/miden-agglayer/src/lib.rs
Comment thread crates/miden-agglayer/build.rs Outdated
Comment thread crates/miden-testing/tests/agglayer/network_account_regression.rs
Comment thread crates/miden-testing/tests/agglayer/network_account_regression.rs Outdated
partylikeits1983 and others added 5 commits May 12, 2026 09:52
Co-authored-by: Marti <marti@miden.team>
Mirrors the constructor pattern used by B2AggNote, ConfigAggBridgeNote, and
UpdateGerNote. Addresses review feedback on #2818.
- bridge_rejects_tx_script: also consume an allowlisted UPDATE_GER input note,
  proving the tx-script check fires independently of the input-note check.
- bridge_rejects_non_allowlisted_input_note: replace the generic NoteBuilder
  note with an attack script that lexically mirrors B2AGG's bridge entrypoint
  (call.bridge_out::bridge_out) but resolves to a different script root, so
  the bridge rejects it even though it looks like an allowed note.

Addresses review feedback on #2818.
Calling bridge_out::bridge_out from the test isn't feasible — its input
preconditions panic before the @auth_script allowlist check can fire, so
the test would see the wrong error. Since the allowlist check is purely
on script root, a minimal script with a non-allowlisted root suffices.
@partylikeits1983
Copy link
Copy Markdown
Contributor Author

Noted. Will cherry-pick into the agglayer branch once this lands on next.

Copy link
Copy Markdown
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thank you!

@PhilippGackstatter
Copy link
Copy Markdown
Contributor

(Merged next so I can use #2847 in #2900.)

Copy link
Copy Markdown
Collaborator

@mmagician mmagician left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM thanks for applying the review changes!

@mmagician mmagician added this pull request to the merge queue May 13, 2026
Merged via the queue into next with commit 7e24cb0 May 13, 2026
18 checks passed
@mmagician mmagician deleted the ajl-agglayer-network-account branch May 13, 2026 21:46
partylikeits1983 pushed a commit that referenced this pull request May 14, 2026
Pulls in `next` so the changelog includes both v0.15.0 Fixes entries
(#2818 AuthNetworkAccount and #2911 asset-in-storage MINT bind),
and ports the new regression test in this branch
(`test_mint_cannot_be_consumed_by_unrelated_faucet`) to the renamed
`ClaimNote::create` API from #2849 (`c738f26e refactor(agglayer):
move create_claim_note into impl ClaimNote::create`).

No production logic changes from this branch; CHANGELOG auto-merged
cleanly (both bullets coexist under v0.15.0 Fixes) and the bridge_in
test file was the only call site still using the old free function.
partylikeits1983 pushed a commit that referenced this pull request May 14, 2026
PR #2818 installed `AuthNetworkAccount` on both the AggLayer bridge AND
the AggLayer faucet (with `allowed_notes() = {MintNote, BurnNote}`), but
only added regression tests for the bridge side. Pre-push code-review
flagged the gap.

Adds two faucet-side tests symmetric to `bridge_rejects_tx_script` and
`bridge_rejects_non_allowlisted_input_note`:

- `faucet_rejects_tx_script`: any transaction submitting a tx script
  against an AggLayer faucet aborts with
  `ERR_NOTE_SCRIPT_ALLOWLIST_TX_SCRIPT_NOT_ALLOWED`.
- `faucet_rejects_non_allowlisted_input_note`: any input note whose
  script root is neither MINT nor BURN aborts with
  `ERR_NOTE_SCRIPT_ALLOWLIST_NOTE_NOT_ALLOWED`.

Without these, a future refactor that drops the faucet's auth component
or breaks its allowlist would keep the suite green and re-open the
forged-MINT attack surface that #2797 / #2818 set out to close.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agglayer PRs or issues related to AggLayer bridging integration pr-from-maintainers PRs that come from internal contributors or integration partners. They should be given priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NoAuth on the bridge account lets anyone emit bridge-authored MINT notes

4 participants