Back to skills
SKILL.md
Crane Access
ASecurityThis skill should be used when the user asks about "access control", "onlyOwner", "onlyOperator", "ownership transfer", "MultiStepOwnable", "ERC8023", "operable pattern", "function-level permissions", "reentrancy protection", "reentrancy lock", or needs to restrict function access in Crane Diamond contracts.
- 9 stars
- 0 votes
- 0 copies
- 4 views
- Added September 10, 2026
Security analysis
100/100Pro scans all 2 files and shows the line behind each finding
npx -y skills add cyotee/indexedex --skill crane-access --agent claude-codeAre you the author of Crane Access?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/cyotee-crane-access)---
name: crane-access
description: This skill should be used when the user asks about "access control", "onlyOwner", "onlyOperator", "ownership transfer", "MultiStepOwnable", "ERC8023", "operable pattern", "function-level permissions", "reentrancy protection", "reentrancy lock", or needs to restrict function access in Crane Diamond contracts.
license: MIT
---
# Crane Access Control Components
Crane provides three access control patterns for Diamond proxies: MultiStepOwnable (ERC-8023), Operable, and ReentrancyLock.
## Component Selection
| Need | Component | Purpose |
|------|-----------|---------|
| Ownership with time-lock | MultiStepOwnable | Two-step ownership transfer with buffer period |
| Delegated permissions | Operable | Global and function-level operator authorization |
| Reentrancy protection | ReentrancyLock | Transient storage lock for cross-function reentrancy |
## Quick Start: Add Access Control
```solidity
// Import modifiers
import {MultiStepOwnableModifiers} from "@crane/contracts/access/ERC8023/MultiStepOwnableModifiers.sol";
import {OperableModifiers} from "@crane/contracts/access/operable/OperableModifiers.sol";
import {ReentrancyLockModifiers} from "@crane/contracts/access/reentrancy/ReentrancyLockModifiers.sol";
// Use in your Target contract
contract MyTarget is MultiStepOwnableModifiers, OperableModifiers, ReentrancyLockModifiers {
function adminOnly() external onlyOwner {
// Only owner can call
}
function operatorOnly() external onlyOperator {
// Global operators or function-specific operators
}
function ownerOrOperator() external onlyOwnerOrOperator {
// Either owner or operator can call
}
function noReentrant() external nonReentrant {
// Protected from reentrancy
}
}
```
## MultiStepOwnable (ERC-8023)
Time-locked two-step ownership transfer with buffer period.
### Storage
```solidity
struct Storage {
address owner;
address pendingOwner;
bool pendingOwnerConfirmed;
uint256 ownershipBufferPeriod; // e.g., 1 days
uint256 bufferPeriodEnd;
}
```
### Ownership Transfer Flow
1. **Initiate**: Owner calls `initiateOwnershipTransfer(newOwner)`
2. **Wait**: Buffer period must elapse
3. **Confirm**: Owner calls `confirmOwnershipTransfer(newOwner)`
4. **Accept**: New owner calls `acceptOwnershipTransfer()`
```solidity
// Step 1: Current owner initiates
MultiStepOwnableRepo._initiateOwnershipTransfer(newOwner);
// Step 2: Wait for buffer period (e.g., 1 day)
// Step 3: Current owner confirms
MultiStepOwnableRepo._confirmOwnershipTransfer(newOwner);
// Step 4: New owner accepts
MultiStepOwnableRepo._acceptOwnershipTransfer();
// Owner can cancel anytime before acceptance
MultiStepOwnableRepo._cancelPendingOwnershipTransfer();
```
### Guard Functions
```solidity
// Revert if msg.sender is not owner
MultiStepOwnableRepo._onlyOwner();
// Revert if msg.sender is not pending owner
MultiStepOwnableRepo._onlyPendingOwner();
```
### Modifiers
```solidity
modifier onlyOwner() {
MultiStepOwnableRepo._onlyOwner();
_;
}
```
### Initialization
```solidity
// In DFPkg.initAccount()
MultiStepOwnableRepo._initialize(
initialOwner, // First owner
1 days // Buffer period for transfers
);
```
## Operable Pattern
Delegated authorization for global and function-level permissions.
### Storage
```solidity
struct Storage {
mapping(address => bool) isOperator; // Global operators
mapping(bytes4 func => mapping(address => bool)) isOperatorFor; // Function-level
}
```
### Authorization Levels
1. **Global Operator**: Can call any function protected by `onlyOperator`
2. **Function Operator**: Can only call specific functions
### Setting Permissions (Owner Only)
```solidity
// Grant/revoke global operator status
OperableRepo._setOperatorStatus(operatorAddress, true); // Grant
OperableRepo._setOperatorStatus(operatorAddress, false); // Revoke
// Grant/revoke function-level operator
OperableRepo._setFunctionOperatorStatus(
IMyContract.someFunction.selector, // Function selector
operatorAddress, // Operator
true // Approval
);
```
### Checking Permissions
```solidity
// Check global operator
bool isGlobal = OperableRepo._isOperator(account);
// Check function operator
bool isForFunc = OperableRepo._isFunctionOperator(
IMyContract.someFunction.selector,
account
);
```
### Guard Functions
```solidity
// Revert if not global OR function operator for msg.sig
OperableRepo._onlyOperator();
// Revert if not owner AND not operator
OperableRepo._onlyOwnerOrOperator();
```
### Modifiers
```solidity
// Only global or function-level operators
modifier onlyOperator() {
OperableRepo._onlyOperator();
_;
}
// Owner OR any operator
modifier onlyOwnerOrOperator() {
OperableRepo._onlyOwnerOrOperator();
_;
}
```
## ReentrancyLock
Transient storage-based reentrancy protection (EIP-1153).
### Usage
```solidity
modifier nonReentrant() {
ReentrancyLockRepo._onlyUnlocked();
ReentrancyLockRepo._lock();
_;
ReentrancyLockRepo._unlock();
}
```
### Functions
```solidity
// Lock the reentrancy guard
ReentrancyLockRepo._lock();
// Unlock the reentrancy guard
ReentrancyLockRepo._unlock();
// Check if locked
bool locked = ReentrancyLockRepo._isLocked();
// Revert if locked (guard function)
ReentrancyLockRepo._onlyUnlocked();
```
### Benefits
- Uses transient storage (cleared after transaction)
- Gas efficient compared to storage-based guards
- Protects against cross-function reentrancy
## Component Files
| Component | Files |
|-----------|-------|
| MultiStepOwnable | `MultiStepOwnableRepo.sol`, `MultiStepOwnableModifiers.sol`, `MultiStepOwnableTarget.sol`, `MultiStepOwnableFacet.sol` |
| Operable | `OperableRepo.sol`, `OperableModifiers.sol`, `OperableTarget.sol`, `OperableFacet.sol` |
| ReentrancyLock | `ReentrancyLockRepo.sol`, `ReentrancyLockModifiers.sol`, `ReentrancyLockTarget.sol`, `ReentrancyLockFacet.sol` |
## AccessFacetFactoryService
Deploy access control facets:
```solidity
import {AccessFacetFactoryService} from "@crane/contracts/access/AccessFacetFactoryService.sol";
// Deploy MultiStepOwnable facet
IFacet ownerFacet = AccessFacetFactoryService.deployMultiStepOwnableFacet(create3Factory);
// Deploy Operable facet
IFacet operableFacet = AccessFacetFactoryService.deployOperableFacet(create3Factory);
// Deploy ReentrancyLock facet
IFacet reentrancyFacet = AccessFacetFactoryService.deployReentrancyLockFacet(create3Factory);
```
## Additional Resources
### Reference Files
For detailed patterns and examples:
- **`references/access-patterns.md`** - Complete access control integration patterns
Files in this skill
- SKILL.md
- references/access-patterns.md
Attribution
Comments
Loading comments…