Skip to content

blockchainBard101/monban

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Monban 🚪

A comprehensive, registry-based access control system for Sui Move.

"Monban" (門番) is Japanese for "gatekeeper". This library provides a standard way to restrict access to your Move functions based on the package ID of the caller, enabling dynamic, composable allow-lists without hardcoding addresses or relying on public(friend).

The Problem

In the Sui ecosystem, you often need to protect sensitive functions (e.g., minting tokens, updating configs, withdrawing funds). Standard Move access control patterns have limitations:

  1. public: Accessible by anyone, including malicious contracts.
  2. public(package): Only accessible within your own package. Too restrictive for composability.
  3. public(friend): Only accessible by modules explicitly declared as friends. This creates a circular dependency or requires you to know all your consumers at compile time.
  4. Capabilities (Objects): Powerful, but passing objects around can be cumbersome for inter-package calls, and managing capability distribution is complex.

What if you want to let a specific external package call your function, but you want to decide which package at runtime?

The Solution

Monban solves this by introducing a dynamic Access Registry.

  1. Registry: You create an AccessRegistry (shared object) for your package.
  2. Whitelisting: You (the admin) add the Package IDs of allowed callers to this registry.
  3. Witness: The caller creates a Witness—proof of their identity—using a One-Time Witness (OTW) or any dropped struct from their package.
  4. Verification: Your protected function checks the Witness against the AccessRegistry.

Because Move structs can only be created by the module that defines them, a Witness created from a struct P::M::MyStruct irrevocably proves the call originated from package P.

Quick Start

1. Installation

Option A: Git Dependency Add monban to your Move.toml:

[dependencies]
monban = { git = "https://github.com/blockchainBard101/monban.git", rev = "testnet/v2" }

Option B: Using MVR (Recommended) Using MVR (Recommended)

mvr add @pkg/monban

2. Setup (In Your Package)

Initialize the registry in your module's init function:

module my_package::my_package;
use monban::monban::{Self, Witness};

public struct MY_PACKAGE has drop {}

public struct Marker has drop, store {}

fun init(otw: MY_PACKAGE, ctx: &mut TxContext) {
    // Create registry and send AdminCap to deployer
    monban::create_and_claim(otw, Marker {}, ctx);
}

3. Protect a Function

Require an AccessRegistry and a Witness in your public functions:

    public fun protected_action(
        registry: &monban::AccessRegistry<Marker>,
        witness: Witness
    ) {

        // Verify allowed access (aborts if unauthorized)
        monban::verify_access(registry, witness);

        // ... Your sensitive logic here ...
    }

4. Grant Access (As Admin)

Use the AdminCap to whitelist a package (e.g., created via a script or CLI):

# Get the Package ID of the caller you want to allow (e.g., 0xabc...def)
sui client call \
    --package $MONBAN_PACKAGE_ID \
    --module monban \
    --function whitelist_package \
    --args $REGISTRY_ID $ADMIN_CAP_ID "0xabc...def" \
    --type-args "$MONBAN_PACKAGE_ID::my_package::Marker" \
    --gas-budget 10000000

5. Call the Function (From Another Package)

The allowed package simply needs to pass any of its own structs to prove its identity:

module allowed_package::caller {
    use my_package::my_package::{Self, Marker};
    use monban::monban::{Self, AccessRegistry};

    // A throwaway struct just for the witness
    public struct MyWitness has drop {}

    public fun execute_call(registry: &AccessRegistry<Marker>) {
        // 1. Create a witness from the passed struct
        let witness = monban::create_witness(MyWitness {});

        // Pass our own struct. Monban extracts our Package ID from this.
        my_package::protected_action(registry, witness);
    }
}

detailed API

monban::create_registry / create_and_claim

Creates a new shared AccessRegistry and returns an AdminCap. Must be called with a One-Time Witness.

monban::whitelist_package

Adds a package ID (string, e.g., "0x123...abc") to the allowed list.

monban::remove_package

Removes a package ID from the allowed list.

monban::create_witness

Converts any drop struct W into a Witness object containing W's package ID.

monban::verify_access

Checks if the Witness's package ID is in the AccessRegistry. Aborts with EUnauthorized if not.


Example Repository

For full working examples, see:

👉 https://github.com/blockchainBard101/monban_examples

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages