---
title: "3. Authorization and Access Rules"
path: "/developers/scrypto/03-authorization-and-badges"
version: "2.7.1"
author: "Hydrate"
createdAt: "2026-02-19T06:44:48.860Z"
updatedAt: "2026-07-29T11:09:36.890Z"
---

# 3. Authorization and Access Rules

## Introduction

In most smart contract platforms, access control is based on the caller's *address* – a pattern that leads to fragile permission systems and common exploits like reentrancy. Radix takes a fundamentally different approach: access is gated by **[badges](https://docs.radixdlt.com/docs/authorization-approach)**, which are standard [resources](/contents/tech/core-concepts/asset-oriented-programming) (fungible or non-fungible) that serve as unforgeable credentials. A caller is authorised not because of *who they are* but because of *what they hold*.

This pattern is central to [Scrypto](/developers/scrypto/01-fundamentals) development and appears in virtually every non-trivial dApp on Radix.

## How It Works

### [Access Rules](https://docs.radixdlt.com/docs/authorization-approach)

When a component is instantiated, its methods can be protected with [access rules](/contents/tech/core-concepts/access-rules-and-auth-zones) that specify which badge(s) must be present for a call to succeed. The [Radix Engine](/contents/tech/core-protocols/radix-engine) checks these rules automatically before executing any method – there is no manual `require(msg.sender == owner)` logic.

```
enable_method_auth! {
    roles {
        admin => updatable_by: [];
        minter => updatable_by: [admin];
    },
    methods {
        mint_tokens => restrict_to: [minter, admin];
        update_price => restrict_to: [admin];
        buy => PUBLIC;
    }
}
```

### [Proofs](https://docs.radixdlt.com/docs/auth) and the Auth Zone

When a method requires a badge, the caller provides a [Proof](/contents/tech/core-concepts/buckets-proofs-and-vaults) – a cryptographic attestation that a resource exists in the caller's possession without transferring it. Proofs can be placed on the **Auth Zone** (a transaction-scoped container) so that multiple method calls within the same transaction can share the same authorisation context.

```
# [Transaction manifest](https://docs.radixdlt.com/docs/learning-to-create-and-use-transaction-manifests): create proof and call restricted method
CREATE_PROOF_FROM_ACCOUNT_OF_AMOUNT
    Address("account_rdx...")
    Address("resource_rdx...admin_badge...")
    Decimal("1")
;
CALL_METHOD
    Address("component_rdx...")
    "update_price"
    Decimal("1.50")
;
```

## Moving Badge-Gated and Restricted Resources

Because authorisation on Radix depends on presenting a [Proof](/contents/tech/core-concepts/buckets-proofs-and-vaults), a resource whose withdrawal is gated by a badge cannot be moved with the Radix Wallet's built-in transfer screen – that flow builds a plain withdraw-and-deposit [transaction manifest](https://docs.radixdlt.com/docs/learning-to-create-and-use-transaction-manifests) and never creates the proof the [access rule](https://docs.radixdlt.com/docs/auth) demands. Moving it requires a manifest – typically supplied by a dApp – that creates the required proof first (the `CREATE_PROOF_FROM_ACCOUNT_OF_AMOUNT` pattern shown above) and then performs the withdrawal within the same transaction.

For dApp builders this means: if your users hold badge-gated assets, give them an in-app action that sends the wallet a correctly-authorised manifest, rather than expecting a manual wallet transfer to succeed. It is also why **soulbound** badges stay put – their Withdraw action is locked outright, so no proof can unlock it.

Wallet support for this may be coming. Two pull requests opened on 23 July 2026 by community developer [genkipool](/ecosystem/genkipool) would have the wallet attach the required badge itself: [sargon #452](https://github.com/radixdlt/sargon/pull/452) injects badge `ResourceSpecifier`s into the `PerAssetTransfers` manifest builder via `create_proof_of_amount` and `create_proof_of_non_fungibles`, and [babylon-wallet-android #1446](https://github.com/radixdlt/babylon-wallet-android/pull/1446) builds the transfer feature on top. Both were still open as of 29 July 2026.

For the full picture of movement rules on a resource – including freeze, recall, and why a deposit rule cannot check what the recipient holds – see [Permissioned and Regulated Assets](/developers/scrypto/09-permissioned-and-regulated-assets).

## Common Badge Patterns

### Admin Badge

The most basic pattern: mint a single non-fungible badge at instantiation and return it to the deployer. Methods like `withdraw_fees`, `update_config`, or `pause` are gated behind this badge.

### User Badge

The [User Badge Pattern](/contents/tech/core-concepts/badges) issues a non-fungible badge to each user when they register. The badge's non-fungible data stores user-specific state (balances, permissions, membership tier). Methods read the caller's badge data to personalise behaviour without maintaining a separate user registry.

### Multi-Signature

[Access rules](https://docs.radixdlt.com/docs/authorization-approach) support boolean logic: `require_n_of(2, [badge_a, badge_b, badge_c])` creates a 2-of-3 multi-sig gate. This is useful for treasury management, protocol upgrades, or any high-stakes operation.

### Soulbound Badges

By creating a non-transferable resource (restrict `Deposit` and `Withdraw` actions), a badge becomes soulbound to the original recipient's account. This is ideal for identity credentials, certificates, or membership tokens that should not change hands.

## Next Steps

- [Events, Metadata, and Royalties](/developers/scrypto/04-events-metadata-royalties) – make your component legible to wallets, indexers, and the Gateway

## External Links

- [Authorization – Proofs – Official Docs](https://docs.radixdlt.com/docs/auth)

- [User Badge Pattern – Official Docs](https://docs.radixdlt.com/docs/user-badge-pattern)

- [Account Deposit Patterns – Official Docs](https://docs.radixdlt.com/docs/account-deposit-patterns)

<Infobox>
| Example | [User Badge Pattern](/contents/tech/core-concepts/badges) |
</Infobox>