# Crane Access

> 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.

- Skill: `majiayu000/crane-access` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds add majiayu000/crane-access`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/crane-access/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/crane-access

---


# 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

