Repository navigation
Conversation
Add proposal to update on-chain execution config
fix: enforce strict bytecode verifier bounds to prevent validator DoS
chore(sync): merge public m1 and rework verifier strict bounds
- new 0x1::transaction_permissions module: ordered allow/deny rule table keyed by sender (specific or all accounts) and transaction kind (deploy/upgrade/script/other); first match wins, no match allows, capped at 256 rules since validation scans unmetered - admin insert/remove entry functions gated by the framework signer, get_rules/check/is_allowed views, module events on every mutation - initialized at genesis; initialize_extension entry for chains upgraded past genesis - TRANSACTION_PERMISSIONS feature flag (226), default off; VM-side enforcement lands separately - regenerated docs and SDK builder (the builder also picks up the earlier delegation-pool partial-voting entry function) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- doc catch-up for earlier delegation-pool partial-voting, staking-contract, and token-objects changes; no source changes Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- OnChainConfig mirror of 0x1::transaction_permissions with first-match-wins verdict lookup; layout pinned by a BCS test - check A at validation: scripts and other transactions, denied with new discard code TRANSACTION_NOT_PERMITTED (claims reserved 46); applies to mempool, execution, and simulation with no gas charged - check B at the code-publish funnel: deploy (no target module exists) vs upgrade, matched on the transaction sender, denied with new kept code MODULE_PUBLISHING_NOT_PERMITTED (claims reserved 1136) so denied publishes still pay gas; catches publishes from scripts, multisig, and object code deployment - self-bricking guard hardcoded in both checks: approved governance scripts, framework-reserved and core-resources senders, and 0x1::aptos_governance entry functions are never denied - e2e tests: feature gating, first-match ordering, wildcard and per-sender rules, script/entry/deploy/upgrade denial, deny-all recovery through the exempt framework account Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- core-resources scripts: initialize table, insert rule (per-sender and wildcard), remove rule, enable/disable feature 226 - operator runbook: rollout order, rule semantics, listing via the view API, first-match ordering guidance, emergency disable, and the governance-proposal path after core-resources decommissioning - all six scripts compile against the framework Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Rule gains an optional module pattern (address, optional module
name); rules without one behave as before, rules with one apply
per module: published modules for deploy/upgrade kinds, loaded
modules for script/other kinds
- module access is enforced by a storage decorator around the user
payload session, so entry points, transitive calls, resource-type
loads, closures, and lazy loading are all covered; a mid-execution
denial is kept and charged (new code MODULE_ACCESS_DENIED, claims
reserved 1137), while an entry function's own module is pre-checked
at validation and discarded free
- publish checks now classify and judge each bundle module
separately; module patterns enable per-module publish allowlists
- special addresses (0x0..0xf) are always accessible and cannot be
targeted by a pattern; system sessions and the publish process
keep raw storage
- new entry functions insert_module_rule_for_{sender,all}, view
check_module_access, migration scripts and runbook section;
5 new e2e tests, 6 new Move unit tests, 3 new Rust config tests
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
seanyoung
force-pushed
the
sean/tx-perms
branch
from
October 7, 2026 08:29
8b7055f to
e10a0b7
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Transaction Permission Table
Adds an on-chain, governance-managed rule table that decides whether a transaction
is allowed to run, enforced by the VM behind a new feature flag (off by default).
How it works
Each rule matches a sender (a specific account, or all accounts) and a
transaction kind — deploy (
0), upgrade (1), script (2), other (3) —and carries an allow/deny verdict. Rules are evaluated in order, first match
wins, and no match means allow, so an empty table changes nothing. Rules match
the primary transaction sender (fee-payer, multi-agent, and multisig included).
Enforcement happens at two points, because no single point can classify all
four kinds:
validate_signed_transaction): scripts and "other"transactions. A denial discards with the new status code
TRANSACTION_NOT_PERMITTED(claims reserved slot 46) — no gas charged, andit applies uniformly to mempool admission, execution, and simulation.
resolve_pending_code_publish_and_finish_user_session):deploy vs. upgrade, where upgrade means any target module already exists.
This catches every publish path, including publishes from scripts, multisig,
resource accounts, and object code deployment. A denial fails the transaction
with the new kept status code
MODULE_PUBLISHING_NOT_PERMITTED(reservedslot 1136), so denied publishes still pay gas and are not free compute.
A script that publishes code must pass both the script rules and the
deploy/upgrade rules.
Self-bricking guard
Hardcoded in the VM, not expressible in the table: approved governance scripts,
framework-reserved senders (0x1–0xa), the core-resources account, and
0x1::aptos_governanceentry functions are never denied. A deny-all tabletherefore cannot lock out the governance path needed to fix it (covered by a
dedicated e2e test).
Changes
0x1::transaction_permissionsmodule —vector<Rule>under
@aptos_frameworkcapped at 256 entries (the scan runs unmetered invalidation); admin entry functions gated by the framework signer
(
insert_rule_for_sender,insert_rule_for_all,remove_rule,initialize_extension);get_rules/check/is_allowedviews; eventson every mutation; initialized from genesis for new chains.
TRANSACTION_PERMISSIONS = 226(fork range), wired infeatures.move,aptos_features.rs, and the release builder. Default off.OnChainConfigmirror of the resource (BCS layout pinned by a unittest) and the two enforcement checks above.
movement-migration/tx-permissions/— core-resources scriptsfor initialize, rule edits, and feature enable/disable, plus an operator
runbook (rollout order, listing via the view API, emergency disable, and the
governance-proposal path once core-resources is decommissioned).
Note: the admin entry points are split into
_for_sender/_for_allvariants because the SDK transaction-builder generator cannot encode
Option<address>arguments; a publicinsert_rule(Option<address>, ...)remains for governance scripts.
Testing
matching, remove-shift, signer gating, bounds and cap) — all 679 framework
Move tests pass.
e2e-move-tests/src/tests/transaction_permissions.rs): featuregating off/on, wildcard and per-sender rules, script/entry/deploy/upgrade
denial with the expected status codes, and deny-all recovery through the
exempt framework account.
the Move struct.
Rollout
the enforcement code).
initialize_transaction_permissions.move(one-time, idempotent).enable_transaction_permissions.move(enables flag 226 + epoch change).disable_transaction_permissions.moveis the emergency off switch; it leavesthe table intact.
🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.