Ownable vs AccessControl vs AccessManager in Solidity
Quick answer. Use Ownable2Step for a single contract with one admin, AccessControl when one contract needs separate powers, and AccessManager when many contracts share one permission system with delays. In every case, put the admin behind a multisig.
Video transcript
Access control decides who can mint, pause, upgrade and move funds. Each OpenZeppelin model fails in its own way.
OWASP's Smart Contract Top 10 for 2026 ranks access control vulnerabilities first.
Use Ownable2Step for one admin on one contract, AccessControl for separate powers, and AccessManager when many contracts share one permission system.
Ownable2Step fixes the handoff, not renounceOwnership. One call can still set the owner to the zero address.
Audits found it at Ethena, Yellow Network and Kairos, risking frozen settings and locked treasury funds. If an owner is always required, override it to revert.
In AccessControl, one admin role controls every role by default, which OpenZeppelin warns carries significant risk. The Default Admin Rules extension allows one admin, moved in two steps with a delay.
Audits also find a second top admin, owners and roles out of step, role math that could collapse to the default admin, and zero delays.
AccessManager keeps every permission in one contract. Mark sensitive functions restricted, give the admin role to a multisig, and run version five point seven or later.
The top key decides everything, so hold it in a multisig. Guardian audits start with a design review, then attack privileged flows. After launch, Managed Security monitors role changes.
Read the full guide for upgradeable variants and every finding. Or get your roles reviewed before launch at guardian.security.
Access control decides who can mint, pause, upgrade and move funds. OWASP's Smart Contract Top 10 for 2026 ranks access control vulnerabilities first.
OpenZeppelin Contracts offers three models for it. This guide follows the current release, v5.7.0, published July 29, 2026.
Each model fails in its own way. Here is how they compare, what audits find in each, and how to choose.
The Three Models at a Glance
| Contract | Who holds power | How power moves | Best for |
|---|---|---|---|
Ownable | One owner address | One call, takes effect at once | Simple contracts, prototypes |
Ownable2Step | One owner address | New owner must accept | Single-admin contracts in production |
AccessControl | Holders of bytes32 roles | Each role's admin grants and revokes | One contract with several distinct powers |
AccessControlDefaultAdminRules | Roles, with one top admin | Top admin moves in two steps, with a delay | Roles with a hardened top admin |
AccessManager | uint64 roles in one central contract | Grants, calls and admin changes can be delayed | A system of many contracts |
The extensions matter as much as the base contracts. They fix the handoff mistakes audits keep finding.
Ownable and Ownable2Step
Ownable gives one address, the owner, exclusive access to functions marked onlyOwner. OpenZeppelin calls it "perfectly reasonable for contracts that have a single administrative user".
Since v5.0, its constructor takes an initialOwner and reverts on address(0).
Plain transferOwnership hands over control in one call. Send it to a wrong address, or to a contract that cannot call this one, and the admin functions are lost.
Ownable2Step splits the handoff. Nothing changes until the new owner calls acceptOwnership.
What audits find
The common trap: Ownable2Step does not override renounceOwnership. One call still sets the owner to address(0), and it clears any pending owner too.
- Ethena L-04: renouncing would have frozen every
onlyOwnersetting onEthenaSafeGuard. - Yellow Network L-04: renouncing during the handoff to a Timelock could lock treasury funds for good.
- Kairos L-12: the inherited function bypassed a three-day renouncement process.
All three were resolved. If a contract must always have an owner, override the function to revert:
error RenounceDisabled();
function renounceOwnership() public pure override {
revert RenounceDisabled();
}
AccessControl and Admin Roles
AccessControl splits power into roles, each a bytes32 id checked with onlyRole. A minter can mint without being able to pause.
Holding a role does not let you grant it. Each role has an admin role, and only its holders can call grantRole and revokeRole.
By default, DEFAULT_ADMIN_ROLE (0x00) is the admin of every role, including itself. OpenZeppelin warns that it "carries significant risk".
To reduce that risk, OpenZeppelin recommends AccessControlDefaultAdminRules. It allows one default admin, and moving that role takes two steps with a configurable delay.
The base contract cannot list role holders onchain. Index the RoleGranted and RoleRevoked events, or use AccessControlEnumerable.
What audits find
- A second top admin. In Bracket L-13, a vault creator could take
DEFAULT_ADMIN_ROLEand revoke the multisig. - Owner and roles out of step. In Trueo L-01, a former owner could keep
DEFAULT_ADMIN_ROLEandPAUSER_ROLE. - Custom role math. In Strata M-02, a derived role id could collapse to
bytes32(0), the default admin. - A zero delay. Glider I-03 set the default admin delay to zero, removing the review window.
For the wider bug patterns, see access control vulnerabilities in smart contracts.
AccessManager for Many Contracts
AccessManager arrived in v5.0 in October 2023. It "stores all the permissions in a single contract", so a protocol has one place to audit.
Managed contracts inherit AccessManaged and mark functions restricted. The manager maps each function selector on each contract to one role.
Roles are uint64 numbers, not names. ADMIN_ROLE is 0, and every address holds PUBLIC_ROLE.
Until configured, every restricted function is open only to ADMIN_ROLE. Delays are built in:
- Execution delay: set per member; the call is scheduled, then executed after the wait.
- Grant delay: set per role; a new member's role takes effect later.
- Target admin delay: set per contract; covers its function roles, closing it and changing its authority.
Each role also has a guardian that can cancel scheduled operations. Admins can close a whole contract with setTargetClosed during an incident.
What to check
- Every sensitive function carries
restricted. Without it, the manager's rules "won't be applied". restrictedsits onexternalfunctions. OpenZeppelin warns internal use can have "critical security implications".- A multisig or governance holds
ADMIN_ROLE, the default admin and guardian of every role. - Contracts moved from
Ownablenow see the manager asmsg.sender. - You run 5.7.0 or later. It stops
executefrom bypassing the delay onupdateAuthority.
Which Model to Use
| If you need | Use |
|---|---|
| One admin for one contract | Ownable2Step, owned by a multisig |
| Separate powers in one contract | AccessControl with AccessControlDefaultAdminRules |
| Role holders readable onchain | Add AccessControlEnumerable |
| One permission map across many contracts | AccessManager |
| Delays on sensitive calls and grants | AccessManager, or a TimelockController as admin |
| Contracts behind a proxy | The upgradeable variant of the same contract |
Behind a proxy
Each model has a twin in @openzeppelin/contracts-upgradeable, such as OwnableUpgradeable and AccessManagerUpgradeable.
Constructors become initializers, like __Ownable_init(initialOwner). Skipping one can leave a contract with no owner; see five upgradeable contract vulnerabilities.
From v5.0, these variants use ERC-7201 namespaced storage. A live v4 proxy cannot switch to them in place, as our v4 to v5 migration guide explains.
Whichever model you pick, the top key decides everything. Hold it in a multisig, following our multisig best practices.
How Guardian Reviews Access Control
A Guardian smart contract audit starts with a design review of governance, roles and upgrade paths, before implementation locks in the expensive risks.
Senior researchers then attack privileged flows with exploit-driven review.
Vanguard puts two independent teams on the same scope and reviews updates for six months after production.
After launch, Managed Security monitors privileged calls, role and ownership changes and upgrades on every block.
Frequently Asked Questions
Is Ownable2Step safer than Ownable?
For transfers, yes: the new owner must call acceptOwnership, so a typo cannot hand the contract to a dead address. But renounceOwnership is still a single call in both, so override it if the contract must always have an owner.
What is DEFAULT_ADMIN_ROLE in AccessControl?
It is the role with id 0x00 that administers every role by default, including itself. Whoever holds it can grant and revoke those roles. AccessControlDefaultAdminRules limits it to one account and moves it in two steps with a delay.
When should I use AccessManager instead of AccessControl?
When several contracts need permissions you want to see and change in one place, or when you want delays on grants and sensitive calls. For one contract with a few roles, AccessControl is simpler.
Can an Ownable contract move to AccessManager?
Yes. OpenZeppelin's docs say to transfer ownership to the manager. After that, onlyOwner functions are called through the manager's execute function, and the contract sees the AccessManager as msg.sender.
Sources
- OpenZeppelin Docs: Access Control, Contracts 5.x
- OpenZeppelin Contracts (GitHub): Release v5.7.0 (July 29, 2026)
- OpenZeppelin Contracts (GitHub): CHANGELOG, 5.0.0 (October 5, 2023) to 5.7.0
- OpenZeppelin Contracts (GitHub): Ownable2Step.sol, v5.7.0
- OpenZeppelin Contracts (GitHub): AccessControl.sol, v5.7.0
- OpenZeppelin Contracts (GitHub): AccessControlDefaultAdminRules.sol, v5.7.0
- OpenZeppelin Contracts (GitHub): AccessManager.sol, v5.7.0
- OpenZeppelin Contracts (GitHub): AccessManaged.sol, v5.7.0
- OpenZeppelin Contracts Upgradeable (GitHub): access contracts, v5.7.0
- OWASP: Smart Contract Top 10, 2026
- Guardian: Ethena Execution Guard (April 2, 2026)
- Guardian: Yellow Network Yellow Contract (March 8, 2026)
- Guardian: Kairos Protocol Review (July 9, 2026)
- Guardian: Bracket LST Vault, Round 2 (March 22, 2025)
- Guardian: Trueo Staking Updates (April 23, 2026)
- Guardian: Strata Tranches (October 10, 2025)
- Guardian: Glider Protocol Review (September 18, 2026)
Get your roles reviewed before launch
Guardian reviews who can mint, pause and upgrade your contracts, and how that power moves, before an attacker tests it.