For the complete documentation index, see llms.txt. This page is also available as Markdown.

Runtime RBAC

The RuntimeRBAC class provides type-safe access to Bloxchain RuntimeRBAC contracts with dynamic role-based access control and flexible permission management.

🎯 Overview

RuntimeRBAC extends BaseStateMachine with advanced role management:

  • Dynamic role creation and management via batch configuration

  • Flexible permission system with function-level access control

  • Meta-transaction support for role operations

  • Event-driven role updates for external monitoring

Note: Function schema registration has been moved to GuardController for better architectural separation. RuntimeRBAC focuses on role and permission management, while GuardController handles execution control and function schema management.

🚀 Quick Start

import { RuntimeRBAC } from '@bloxchain/sdk/typescript'
import { createPublicClient, createWalletClient, http } from 'viem'
import { mainnet } from 'viem/chains'

// Initialize clients
const publicClient = createPublicClient({
  chain: mainnet,
  transport: http()
})

const walletClient = createWalletClient({
  account: privateKeyToAccount('0x...'),
  chain: mainnet,
  transport: http()
})

// Create RuntimeRBAC instance
const runtimeRBAC = new RuntimeRBAC(
  publicClient,
  walletClient,
  '0x...', // contract address
  mainnet
)

📖 Core Features

1. Role Management

Get Role Information

Check Account Role

Get Authorized Wallets in Role

Get Roles for Wallet

Get Supported Roles

2. Function Schema Management

Get Function Schema

Get Supported Functions

3. Permission Management

Get Active Role Permissions

Check Action Permission

Handler vs execution selectors (how EngineBlox enforces wiring)

Role permissions store a handlerForSelectors array on each FunctionPermission. On-chain behavior is split as follows (see contracts/core/lib/EngineBlox.sol):

  1. Grant time (addFunctionToRole): _validateHandlerForSelectors checks that every entry in the permission’s handlerForSelectors is allowed by the function schema for that functionSelector when the schema has enforceHandlerRelations (strict mode). This does not re-run on every hasActionPermission read.

  2. Runtime permission (hasActionPermission / roleHasActionPermission): Only whether the wallet’s roles include the functionSelector and the TxAction bitmap. The stored handlerForSelectors list on the role is not consulted again on each call.

  3. Meta / dual-selector paths (_validateExecutionAndHandlerPermissions): Requires hasActionPermission for both executionSelector and handlerSelector. If the handler function schema has enforceHandlerRelations, the engine also requires executionSelector to appear in functions[handlerSelector].handlerForSelectors — a global handler→execution graph on the schema, independent of which role row granted access.

  4. Flexible schemas: If enforceHandlerRelations is false for a schema, that global pairing check is skipped by design. The @custom:security OPERATIONAL MODES discussion (strict vs flexible handler wiring) lives on EngineBlox.registerFunction in contracts/core/lib/EngineBlox.sol—that is the schema-registration entry point (this repository does not expose a separate registerFunctionSchema symbol). When wiring roles, whitelists, and meta-tx flows in production, follow the action ordering and batch constraints in contracts/core/access/lib/definitions/RuntimeRBACDefinitions.sol (role-config / meta) and contracts/core/execution/lib/definitions/GuardControllerDefinitions.sol (guard-config / macros) so schemas, grants, and calls stay consistent.

🔄 Batch Configuration Workflow

RuntimeRBAC uses batch configuration for all role and function management operations. This allows multiple changes to be applied atomically via meta-transactions.

Role Configuration Actions

The batch system supports the following action types:

Create Role via Batch

Add Wallet to Role via Batch

Add Function Permission to Role via Batch

Note: The function schema must be registered via GuardController before adding permissions.

📡 Event Monitoring

Listen for Role Configuration Events

Contracts emit ComponentEvent(bytes4 functionSelector, bytes data). For RBAC config, filter by executeRoleConfigBatch selector and decode data as (RoleConfigActionType, bytes32 roleHash, bytes4 functionSelector, address wallet). See generated contract API and NatSpec.

🛡️ Security Features

1. Role Protection

Protected roles (OWNER_ROLE, BROADCASTER_ROLE, RECOVERY_ROLE) cannot be removed:

2. Wallet Limits

Roles have maximum wallet limits:

3. Function-Level Permissions

Fine-grained permission control with action-level permissions:

4. Function Schema Protection

Protected function schemas cannot be unregistered:

🔧 Advanced Usage

Batch Role Operations

Function Registration Workflow

Note: Function schema registration is now handled by GuardController. Use GuardController's guardConfigBatchRequestAndApprove with the REGISTER_FUNCTION action.

🧪 Testing

Unit Testing

Integration Testing

🚨 Common Issues

Issue: "Role is protected"

Solution: Protected roles (OWNER_ROLE, BROADCASTER_ROLE, RECOVERY_ROLE) cannot be removed. Use a different role or create a new one.

Issue: "Role has reached maximum wallet limit"

Solution: Increase the role's wallet limit or revoke roles from other accounts before adding new ones.

Issue: "Function schema not found"

Solution: Register the function schema via GuardController before adding it to a role. Use GuardController's guardConfigBatchRequestAndApprove with REGISTER_FUNCTION action.

Issue: "Insufficient permissions"

Solution: Ensure the account has the required role and function permissions. Check with hasActionPermission.

Issue: "Invalid role hash"

Solution: Use the correct role hash. Generate it using keccak256(abi.encodePacked(roleName)).

Issue: "Handler selector mismatch"

Solution: Ensure handlerForSelectors array in function permission matches the function schema's handlerForSelectors array. Use bytes4(0) for execution selectors.

Issue: ResourceAlreadyExists when adding a function to a role

Solution: Re-adding the same selector with RoleConfigActionType.ADD_FUNCTION_TO_ROLE hits the same ResourceAlreadyExists revert as a direct addFunctionToRole would when the selector is already on the role. To change the stored permission bitmap or handlerForSelectors, include RoleConfigActionType.REMOVE_FUNCTION_FROM_ROLE in a roleConfigBatchRequestAndApprove → executeRoleConfigBatch flow first, then ADD_FUNCTION_TO_ROLE with the new values—the engine applies removal through that batch path; there is no supported separate public removeFunctionFromRole entrypoint for integrators. Note: for registered selectors, removeFunctionFromRole reverts with GrantNotRevocable when the schema's isGrantRevocable is false; when true, grants may be removed from protected roles (OWNER / BROADCASTER / RECOVERY) as well as custom roles.


Last updated

Was this helpful?