Replacing Besu onchain permissioning after its removal starts with an inventory of rules
If your permissioned Besu network used a smart contract to decide which accounts could onboard, transact or be suspended, the first job is not writing code. Besu 25.6.0 (June 4, 2025) removed onchain permissioning, so that contract no longer enforces anything on upgraded nodes, and the rules it held must be found, written down and re-expressed before any node moves forward. Effort on this work comes mainly from three things: inventorying the rules the contract actually enforced, re-expressing each one as local node or account permissions or as a permissioning plugin, and getting every operator to agree on the result. The first driver is how many rules the contract held and how many of them have no obvious local equivalent. The second is how many operators must sign off, since each one must apply the same rules at the same time.
DeployOpen scopes this work in writing before it starts. A typical written scope for this change lists the contract and its functions that the network relied on, the rule-by-rule mapping to local node permissioning, account permissioning or a plugin, the configuration files and plugin code to be delivered, the test cases that prove each rule still holds, the consortium review steps and the cutover runbook. Fixed-scope work is priced from that list, so the number of rules, the number of nodes and the number of organizations involved are the items to put in front of any quote. Ask the partner which items are one-time (the mapping, the plugin build and the first rollout) and which recur (rule changes, onboarding requests and upgrade testing against each new Besu release listed on the Besu releases page).
Before you commit to a scope, confirm three things in your own environment: the exact contract address and the version of Besu your nodes run, the full list of functions the nodes queried, and whether any rule was enforced only through a process outside the chain. Also confirm whether the network will be kept on a release that still supports the contract, since the removal is what forces the change and the Besu sunsetting announcement explains the maintainers' reasoning. Those answers determine whether the inventory takes days of review or a longer consortium exercise, and they should be written into the scope before design begins.
What maps cleanly from onchain permissioning to local permissioning
This table compares the four things onchain permissioning typically did (node allowlisting, account onboarding, suspension and action restrictions) with what Besu local permissioning files cover, and what still needs a plugin or a process change. Read the right-hand column as the work you will own after cutover. The main takeaway is that local files cover the node and account rules on paper, but exact behavior parity with your old contract must be confirmed in your own test environment.
| Capability | Onchain permissioning (removed) | Local permissioning files | Gap to close |
|---|---|---|---|
| Node allowlisting | Contract held the list of enodes allowed to connect, changed by admin transactions | Node permissions file lists allowed enodes on each node, with connection restrictions | Each node file must be edited and distributed; confirm that peers reject connections the way the old contract did |
| Account onboarding | Admin account added new accounts through a contract transaction visible to all nodes | Account permissions file lists allowed accounts per node, with onboarding rules | No single on-chain change propagates; you need a process to update every node file in step |
| Account suspension | Admin suspended an account on chain, effective network-wide once mined | Accounts can be suspended through the local account permissions configuration | Timing differs: a file change takes effect per node, so confirm how quickly nodes apply it |
| Action restrictions | Contract rules governed which actions an account could take | Account permissioning restricts actions as described in the docs | Confirm that the restrictions cover every transaction type your rules need, or plan a plugin |
| Rules beyond the file format | Custom logic, such as approval workflows or conditional rules in contract code | Not expressed directly in the permissions files | Write a permissioning plugin, or move the logic into an approval process outside the chain |
| Consistency across members | One shared on-chain state that every node read | Each operator holds its own copy of the rules | Agree on a change process, versioning and a signed record of each update across the consortium |
Documented options for moving permissioning rules off the chain
Besu gives operators two documented routes for replacing onchain permissioning: local permissions configuration files and the plugin framework. The release notes and removal announcements define what was taken out, so they anchor the migration scope. No documented one-step converter exports old contract state into local files, so pulling current rules out of the contract is work your team or partner must plan.
Local node permissioning file
Node permissioning restricts which peers a node will connect to, using an allowlist of enode identities. For a network that previously used onchain rules for connections, this file becomes the local replacement. Check that every participant's enode URL is listed on every node, and that the file is distributed through the same change process you use for genesis and validator changes. Confirm the exact configuration key and file format against the Besu permissioning documentation for your release.
Local account permissioning file
Account permissioning governs who can submit transactions, covering onboarding, suspending accounts and restricting actions. Onchain rules often held these decisions in a contract that operators could update with a transaction. A local file must be changed on each node, so decide which node or nodes are authoritative for account decisions and how changes reach all of them. Ask whether your use case needs per-account transaction restrictions or only a connection-level allowlist.
Permissioning plugin framework
Besu's modular plugin framework lets a team write custom permissioning logic when a static file cannot express the rules, such as lookups against an internal identity system. The maintainers point teams that still need removed features toward plugins or community forks. Budget for building, testing, versioning and upgrading the plugin with each Besu release, since plugin code depends on the client's internal interfaces. Confirm the plugin API for your target release before design starts.
Release notes as the removal reference
The 25.6.0 release notes record the removal of onchain permissioning, and the maintainers' sunsetting announcement explains the reasoning. Use these documents to define the exact scope of what your network relied on, and to confirm which behaviors have no direct replacement. Pin the release you are moving from and the one you are moving to, and read every release note between them, because later changes can affect permissioning and the upgrade path.
Exporting current onchain rules
No documented one-step converter turns contract state into local permissions files. Your team must read the current allowlist, roles and suspension status from the permissioning contract, reconcile them with what each node actually enforces, and write the results into node and account files. Record the block height of the export so the snapshot can be checked later. Ask any partner to show how they will verify the exported set against the live contract before cutover.
Keeping consortium rules consistent
When several organizations run nodes, a local file on each node can drift apart, and a node with a stale allowlist will accept or reject peers differently from the rest. Agree on a single source of truth for the rules, a signed change process and a record of who approved each change. Test that a deliberately mismatched node is detected before it joins the network. Your governance agreement should name who may change rules and how disputes are resolved.
How local node and account allowlists replace the contract
Local permissioning splits the job the contract used to do into two layers, and each layer is configured on every node rather than once on the chain. Node permissioning decides which peers a node will connect to, restricting connections to known participants. Account permissioning decides which Ethereum accounts may transact and what they may do, covering onboarding rules, suspending an account and restricting specific actions. Before you write any file, map each rule your old contract enforced to one of these two layers. Rules about who may join the network belong mostly in node permissioning, while rules about who may send a transaction, and whether a compromised account can still act, belong in account permissioning. Rules that depended on on-chain state, such as approvals recorded by a voting process, do not translate directly and need a separate design decision.
Each Besu node reads its own permissions configuration file, so there is no single shared list to update. A rule change is therefore a file change on every node that must enforce it, and a node that missed the update will keep applying the old rule. Plan the change as a versioned artifact: keep the permissions files in source control, record which version each operator has deployed, and roll the change out through a defined sequence. Confirm in the Besu permissioning documentation how the files are referenced in your node configuration and whether a node picks up changes without a restart in the release you run. Do not assume either behavior from another version.
Verification has to cover both sides of the rule. For node permissioning, confirm that an unlisted peer is refused and that every listed participant can still connect, because a mistake in either direction can split the network or leave a node isolated. For account permissioning, test an onboarding case, a suspension and a restricted action against a test network before production. Agree in writing with every consortium member who owns each node's file, who approves a change and how a discrepancy between nodes is detected and resolved. These governance steps cost more time than editing the files, and they are where consistency across a consortium is actually maintained.
Sequence for replacing onchain permissioning on a live network
This sequence moves each onchain permissioning rule into a local or plugin-based control that every operator applies the same way, and removes the contract only after the new controls have been proven. Each step ends with a check you can record, so the cutover is a documented decision rather than a single change window.
Inventory every onchain rule and its owner
Before changing anything, list every rule the permissioning contract enforces: which accounts may transact, which nodes may connect, who may add or remove entries, and any suspension or action restrictions. For each rule, record the contract function that enforces it, the current entries, the business owner who approved it, and the operator who holds the admin key. Confirm the list against the contract's on-chain state and against the governance records of the consortium, since the two often disagree. The output is a signed rule register that every operator has reviewed, with no rule left without an owner.
Map each rule to a local or plugin control
For each entry in the register, decide where it will be enforced after the change. Node connection rules map to node permissions in the local configuration file. Account rules such as onboarding, suspension or restricted actions map to account permissions, or to a permissioning plugin when the rule needs logic that a static allowlist cannot express. Mark any rule that requires a consortium-wide decision, because those need a shared source of truth. Confirm the mapping against the current Besu permissioning documentation for the release you run. The output is a mapping table that a second engineer has checked line by line.
Pilot the new controls on a non-production network
Build a copy of the network, or a small test network with the same node versions, and apply the local allowlists or plugin to it. Test the cases that matter most: a permitted account transacts, a blocked account is rejected, a new node is admitted or refused, and a suspended account stops submitting transactions. Run the same test scripts against the contract-based setup first so you can compare results. The output is a test log showing that each rule in the register behaves the same way under both controls, with any gaps logged as blockers for the cutover.
Run local rules in parallel with contract decisions
On the live network, run the new local rules alongside the contract, without enforcing them. Each node logs what its local rules would decide for every connection and transaction, and a reconciliation job compares those decisions with the contract's decisions over a defined window. Investigate every disagreement, because a mismatch means either a missing entry or a logic difference. The output is a reconciliation report with zero unexplained differences, reviewed and accepted by the rule owners named in the register.
Back up node data before upgrading in the same window
If the cutover requires a Besu upgrade, take a verified backup of each node's data directory before the first start on the new release. The Besu 26.10.0 release notes state that the Bonsai database upgrades automatically on first start and that older versions cannot open an upgraded database, so a rollback without a backup is not possible. Store backups off the node, test that a restore completes on a spare host, and record checksums. The output is a backup inventory covering every node, with a restore test passed before the upgrade begins.
Coordinate the cutover across all operators
Agree on a single cutover point with every operator, including the time, the order of node changes and the rollback criteria. Each operator deploys the same local allowlists or plugin version, and the consortium confirms the configuration hash of each node before enforcement starts. Stop any contract-based admin actions during the window so that no entry changes while the switch is in progress. The output is a signed cutover record listing each operator's confirmation and a rollback decision point that all parties accept.
Verify enforcement and monitor for rejected traffic
After enforcement begins, confirm that each node rejects and admits connections and transactions as the register specifies, using the same test cases from the pilot. Watch node logs and metrics for unexpected rejections, and treat any unexplained denial as a potential missing entry until proven otherwise. Keep the reconciliation job running for a period agreed in advance by the consortium. The output is a verification record signed by each operator confirming that enforcement matches the register.
Decommission the contract and its admin keys
Once enforcement is verified, retire the permissioning contract from every operational process. Revoke or destroy the admin keys that could have changed contract entries, and confirm that no tooling, runbook or deployment script still calls the contract. Record the final contract state and keep the audit trail with the rule register for future assessments. Be aware that the contract remains on the chain and cannot be removed, so the decommissioning is a control decision, not a deletion. The output is a decommissioning record that names each key revoked and confirms that no operator can change contract state.
When a permissioning plugin is needed instead of static files
Some permissioning rules change rarely, are small enough to list by hand, and can be decided without asking another system. Node permissioning and account permissioning both support local configuration files in Besu, so these rules can usually be expressed as allowlists that every node loads from its own permissions configuration. This keeps the rule set visible in version control, easy to review, and free of custom code that must be patched. A static file is usually the right first choice when the consortium has a short, stable membership list and onboarding happens through a documented change process.
- Node allowlists: list the enode identities of known participants so that peers outside the consortium cannot connect.
- Account allowlists: list the addresses permitted to transact, and record who approved each entry.
- Suspension: remove or block an account in the file when a participant must be cut off, and make sure the change reaches every node.
- Review cadence: treat each file change as a controlled change with a named approver and a rollback path.
- Scale limit: a file works well for a few members but becomes hard to keep identical across many nodes as the list grows.
Confirm the exact file format and reload behavior for your Besu version in the permissioning documentation before you rely on it.
A plugin is justified when the decision to allow an account or connection depends on information that a static file cannot hold. Typical examples are an approval workflow that completes in a ticketing or identity system, a check against an external registry that changes daily, or a rule that depends on data read at the time of the transaction. The Besu plugin framework lets you write this logic in Java and attach it to the node, so the decision is made locally by code you own. The trade-off is that the rule now lives in your software, not in a configuration file.
- External approvals: query an approval service and allow or deny based on its answer.
- Registry checks: validate a participant against a list maintained by a regulator or consortium secretariat.
- Time-bound access: grant rights for a defined window and revoke them without editing files on every node.
- Failure behavior: decide in advance whether the node fails closed or open when the external system is unreachable.
- Audit trail: log each decision with its inputs so that auditors can reconstruct why an account was permitted.
When a rule can be expressed as a reviewed file, prefer the file. Use a plugin only for the rules that genuinely need live data.
The Besu maintainers announced the sunsetting of onchain permissioning along with Tessera privacy, proof of work and fast sync, citing performance, fewer bugs and a simpler codebase. For teams that still need the removed features, the maintainers point toward plugins or community forks rather than an in-tree replacement. This means the functionality is no longer a standard part of the client, and the team that needs it must own the design. Before committing, read the sunsetting announcement and the 25.6.0 release notes so the decision rests on the stated direction of the project.
- Announcement: the sunsetting post explains the reasons and the direction for affected networks.
- Plugin framework: the framework is the supported extension point for custom permissioning logic.
- Community forks: a fork can carry removed behavior, but the fork owner takes on every merge and security fix.
- Ownership: someone inside the consortium or a named implementation partner must be accountable for the code.
- Documentation gap: confirm which internal interfaces a plugin may call, since these can change between releases.
Ask your team to confirm which plugin interfaces are documented for the release you plan to run.
A permissioning plugin is not a one-time build. Each Besu release can change the interfaces the plugin depends on, so every upgrade needs a compile, test, and redeployment cycle before nodes are updated. Besu ships roughly every month, which means the cost recurs for as long as the network runs the plugin. Budget for this maintenance at the start, because a plugin that is cheap to build can be expensive to keep current. The cost is not a figure this page can provide, so ask for it in writing.
- Build and test: each release requires compiling against the new version and running permissioning tests on a non-production network.
- Compatibility review: read the release notes for changes to plugin APIs, permissioning behavior, and the JDK requirement.
- JDK changes: Besu 26.6.0 requires JDK 25 to build and run, so plugin build chains may need updating too.
- Coordinated rollout: every node must enforce the same rules, so upgrades must be sequenced across all operators.
- Ownership transfer: document who maintains the plugin when the original developer leaves.
When requesting a quote, ask what upgrade and testing work is included, how often it is planned, and who pays for it after go-live.
The choice should be recorded as a decision with inputs, owners, and a test plan. Start by listing every permissioning rule the old network enforced, then classify each as static or dynamic. If all rules are static, a local allowlist is usually simpler to audit and operate. If any rule depends on live data, decide whether that rule can be moved into a reviewed process that updates a static file, since this removes the plugin entirely. Only when that is not possible should the team build and verify a plugin.
- Rule inventory: record each rule from the legacy network with its owner and source.
- Classification: mark each rule as static or dynamic and explain the reason.
- Fail-safe design: test what each node does when its inputs are missing or stale.
- Consistency test: confirm that all nodes reach the same allow or deny decision for the same account and connection.
- Decision record: store the chosen approach, its trade-offs, and its upgrade owner with the network documentation.
Confirm the rule inventory with all consortium members before the build begins, since a rule missed at this stage becomes a gap in every node.
What usually goes wrong when permissioning moves off the chain
Moving permissioning from smart contracts to local files and plugins shifts control to each operator. The risks below share one root cause: rules and state that used to sit in one place now live on every node, so drift, cutover mistakes and upgrade surprises appear where no one is watching.
Rule drift between permission files
Each operator keeps its own node and account permissions file, so a small edit on one node can leave the consortium with different views of who may connect or transact. Nothing on the chain flags the difference. Prevention: store the permission files in version control, require the same change review for every operator, and compare file hashes across nodes on a fixed schedule. Confirm the file format against the permissioning docs for your Besu version before you write the first file.
Node rejects peers after cutover
When a node switches from onchain to local node permissioning, peers that were admitted under the old rules can be refused, and the network can split into partially connected groups. This often shows up only after a restart. Prevention: stage the new node allowlist on every node before the switch, confirm each node lists every other validator's enode identity, and test peer counts on a non-production copy before cutting over.
Lost onboarding history
Onchain permissioning recorded who was added, suspended or removed, and when, as part of the chain's own history. A local file keeps only the current state, so the reason for an access decision can disappear once the file changes. Prevention: export the existing permissioning state and transaction history before removal, and keep a dated change log with approver names for every future onboarding or suspension decision.
Plugin breaks on a later release
A permissioning plugin is compiled against Besu's plugin interfaces, and a later calendar release can change those interfaces or the JDK it needs. The plugin may then fail to load, or load and enforce nothing. Prevention: pin Besu and plugin versions together, add a startup check that confirms the plugin loaded, and run the plugin's rule tests against each release candidate before it reaches production. Ask your plugin vendor or team which Besu versions they have tested.
Rollback blocked by upgraded database
The Bonsai database upgrades automatically on first start, and older Besu versions cannot open the upgraded data. If a permissioning change ships alongside an upgrade and fails, reverting the binary alone will not restore service. Prevention: take a verified node data backup before any upgrade that accompanies a permissioning change, record the Besu version that wrote it, and rehearse restoring that backup on a test node.
What drives the effort and cost of replacing onchain rules
This table compares the factors that change the effort of moving onchain permissioning rules to local configuration or a plugin, and marks which costs are paid once and which recur. Read it to size the work before asking for a quote, since the number of rules, members and environments usually matter more than the choice of tool. The main takeaway is that the one-time migration is only part of the cost, because plugin upkeep and consortium-wide rule changes continue after cutover.
| Driver | Why it changes effort or cost | One-time or recurring | How to keep it down |
|---|---|---|---|
| Number of onchain rules | Each rule in the old contract must be inventoried, mapped to a local allowlist entry or plugin logic, and tested. Undocumented rules take the longest to find. | One-time (inventory and mapping) | Export current contract state and role holders before scoping, and tag rules as node or account level. |
| Number of member organizations | Every member holds its own nodes and accounts, so onboarding and suspension changes must reach each operator the same way. | Recurring (membership changes) | Agree one change procedure and one source of truth for the rule set before cutover. |
| Dynamic rule changes | If rules change often through transactions, a static file is not enough and a plugin or external source of truth becomes necessary. | Recurring (rule changes and plugin upkeep) | Confirm with members how often changes happen and whether they need to be applied without a node restart. |
| Plugin development and test scope | A custom permissioning plugin must be written, reviewed and tested against the access decisions the old contract made, including edge cases. | One-time (build and test) | Limit the plugin to the decisions the network needs and reuse the existing test cases as the acceptance set. |
| Plugin maintenance across Besu releases | Plugins depend on Besu plugin interfaces, and the project ships roughly monthly, so each upgrade needs a compatibility check. | Recurring (every client upgrade) | Pin the Besu version, keep the plugin in version control, and ask the team to confirm the interface stability for their target release. |
| Number of environments | Development, test, staging and production each need the same rules, and drift between them is a common source of failed cutovers. | One-time per environment, then recurring sync | Generate rule files from one definition and deploy them through the same pipeline everywhere. |
| Consortium-wide coordination | Changing a rule on one node without the others can split access between members, so changes need agreed timing and sign-off from every operator. | Recurring (governance and change windows) | Document an approval process and a rollback plan that all members accept before the first change. |
| Backup and rollback planning | Upgrading Besu to a version that changes the database format means rollback needs a backup taken first, which adds work to each release. | One-time setup, recurring per upgrade | Take and test node data backups before each upgrade, and record the restore steps in the runbook. |
Questions buyers ask before replacing Besu onchain permissioning
Can our own team replace onchain permissioning, or do we need a partner?
Your own team can do it if it already runs Besu nodes, has engineers who can read and write Besu configuration, and has someone who owns the consortium rules. The work splits into three parts: translating each onchain rule into a local permissions file or a plugin, testing the result on a non-production network, and rolling it out to every operator. A partner is most useful where the team lacks Java or plugin experience, where several organizations must agree on one rule set quickly, or where the change must be documented for an audit. Ask any partner for a written scope that lists which of these parts they will carry out and which remain with your team.
What does the client need to provide for this work?
You need named rule owners who can say, for each onchain permission, who may join, who may transact, and who may suspend an account. You also need a consortium decision record, because a rule change on one node without the others can split the network's view of who is allowed. Plan for a test network that mirrors your genesis, node count and current contracts, plus access to the existing permissioning contract's state so the team can export the current allowlist. Ask the partner to confirm which of these inputs they need in writing before the scope is agreed.
How long does the replacement take, and what determines it?
Duration depends on the number of rules, the number of operators that must sign off, whether you need a plugin, and how many environments must be tested before production. A network with a short allowlist and one operator is a very different project from a consortium with many members, custom account roles and several test cycles. No duration is stated here because the supplied facts do not give one. Ask for a timeline that breaks the work into rule inventory, build, test, consortium approval and rollout, and check which of those steps depend on other operators' calendars.
Do we have to write a permissioning plugin?
Not always. Besu's local permissioning covers node permissioning, which restricts connections to known participants, and account permissioning, which can handle onboarding rules, suspending accounts and restricting some actions. These local files are configured per node, so they fit networks whose rules are stable and easy to list. A plugin becomes necessary when a rule depends on data that a static file cannot express, such as an external registry, time-bound approvals or logic that must be checked on every transaction. The maintainers suggest plugins or community forks for teams that still need removed features, so treat a plugin as a deliberate engineering project with its own tests, release process and upgrade checks against each new Besu release.
How do we keep permissioning rules consistent across operators?
Consistency comes from a single source of truth for the rule set, applied to every node through the same change process. Keep the permissions files in version control, require each change to reference a consortium approval, and run the same test suite against every node before it is deployed. Write down which operator is authoritative for each list, because a node that accepts a connection another node rejects will produce confusing peer failures. Automated deployment tooling can push identical files to all nodes, and monitoring should alert when a node's loaded configuration differs from the agreed version. Confirm how your consortium will handle an emergency suspension, since waiting for a full approval cycle may be too slow.
What does a rollback look like after the database upgrade?
A rollback is only straightforward if you take a backup before the upgrade. The Besu 26.10.0 release notes state that the Bonsai database upgrades automatically on first start, and older Besu versions cannot open an upgraded database. That means that once a node has started on a newer release, returning to an older binary requires restoring the pre-upgrade backup, not simply swapping the binary back. Plan the rollback path for each node, test restoring a backup on a non-production node, and record which block height each backup represents. Also check whether your permissioning change depends on the new release, because a rollback may need to restore both the binary and the matching permissions files.
Which risks should we review before changing permissioning?
The main risks are a lockout where legitimate nodes or accounts can no longer connect or transact, a silent divergence where operators hold different rule sets, and an unrecoverable node after an upgrade without a usable backup. Each risk has a control: test lockout scenarios on a copy of the network, use a staged rollout across operators, and keep a documented restore procedure. Ask your partner or internal team to list the controls for each risk and to name who can approve a rollback during a change window.
How DeployOpen scopes and delivers a permissioning migration
DeployOpen plans, implements, tests and documents open-source platforms inside your own infrastructure, and a permissioning migration is scoped the same way. The work runs in your cloud accounts, data centers or closed networks, so node permissions files, account allowlists, the permissioning plugin source and its build pipeline stay under your control from the first day. Before any build starts, the written scope should name which onchain rules are being replaced, which nodes and accounts each rule covers, who owns each local permissions file, and how each consortium member will receive changes. Most engagements are fixed-scope, which means scope, deliverables and timelines are agreed in writing before work begins. Ask for that document to list each deliverable, such as the permissions configuration files, the plugin, the test results and the runbook, with the acceptance criteria for each.
DeployOpen prepares systems, controls and evidence for compliance assessments, but it does not issue audit reports, attestations or certifications. If your organization must show that permissioning controls operate as designed, the deliverables can include the configuration records, change history, test evidence and access review procedures that an independent auditor or certification body will examine. Confirm with your assessor which artifacts they expect before scope is fixed. Ongoing work after go-live, such as tracking new Besu releases, reviewing plugin compatibility on each upgrade and re-running consistency checks when a member onboards, is available as a retainer. A retainer suits teams that lack in-house Besu operators, but it should be scoped as its own written agreement with defined response expectations.
DeployOpen does not publish a price list. A quote follows from the written scope, so the cost of this migration depends on how many nodes and consortium members are involved, whether the plugin is built from scratch or adapted, how many environments need testing, and how much of the consistency process your team takes over. When you request a quote, ask for the cost of each deliverable separately, which items are one-time and which recur under a retainer, and which assumptions about your environment the price depends on. Confirm the Besu release you will run before scoping, since the Besu releases on GitHub page lists the versions your upgrade plan must account for.

