Unlocking Safer, Smarter Access Control in Cadence: Capabilities, Entitlements, and Interfaces Explained

This post breaks down the motivations behind entitlements, how they differ from interfaces and capabilities, and why this matters in the real-world design of secure smart contracts.
Enter Entitlements: A New Layer of Access Control
Entitlements are a way to declaratively control what a reference or capability is allowed to do. While interfaces describe what an object can do via standard functionality, entitlements describe what the holder of a reference is allowed to do with that object.
- Interfaces specify attributes and requirements for the object itself. See the FungibleToken.Vault definition for examples of how the Vault interface requires specific functions and enforces conditions about how those functions behave.
1access(all) resource interface Vault: Receiver, Provider, Balance, ViewResolver.Resolver, Burner.Burnable {
2
3 // The `Vault` resource must implement the functions in: Receiver, Provider, Balance, ViewResolver.Resolver, Burner.Burnable
4
5 // Resource definition removed for brevity
6}
- Entitlements are attributes of the reference to the object that provide access to privileged fields to the holder of the reference. See how the FungibleToken.Vault.withdraw function is `access(Withdraw)`. This means that only those holding a reference to this object with the `Withdraw` entitlement can call this function and only the owner can add the `Withdraw` entitlement to a reference.
1access(Withdraw) fun withdraw(amount: UFix64): @{Vault} {
2
3// Function code removed for brevity
4}
This separation allows developers to define granular, secure access policies for shared resources.
Capabilities vs References To understand how entitlements work, it helps to understand capabilities:
- A reference is a live pointer to an object in memory.
- A capability is a latent, serializable reference. It can be stored and passed around, and turned into a live reference using borrow().
In Cadence, you can store capabilities but not live references. Capabilities are issued by the owner of the target (the object), and the owner can revoke or redirect them. This inversion of control is key to Flow’s secure architecture.
Entitlements in Action: Imagine a next-generation version of CryptoKitties, where each cat NFT is a standalone object that the owner stores in their account and each cat has a name that is a field on itself. Rather than baking the ability to set a name into a public function in the base NFT interface, you could define a naming entitlement.
1// entitlement that provides access to setName
2
3access(all) entitlement Naming
4
5 // base NFT interface with entitled setName()
6
7access(all) resource interface NFT {
8 access(all) let id: UInt64
9 access(all) var name: String
10
11 // Uses the Naming entitlement instead of making it public
12
13 // If it was public, anyone with a reference with the object could call setName
14 // Now, the owner has to specifically create the reference with the Naming entitlement
15 // in order to allow this function to be called by someone with the reference
16
17access(Naming) fun setName(newName: String) {
18 self.name = newName
19 }
20}
Now, when you give someone access to rename a cat, you’re not just giving them a reference to the NFT, you’re giving them a reference decorated with the naming entitlement. Only that reference will allow them to call `setName()`.
This is powerful because:
- The same object can be accessed in different ways by different people.
- You can’t add entitlements to a reference after it’s created, you can only remove them.
- Entitlements compose well with existing access models and can be reused across contracts.
Security by Design - Traditional programming languages like Java, C++, or even Rust focus on protecting developers from themselves by preventing accidental misuse. Cadence, by contrast, is designed for adversarial environments, where developers must protect their contracts from untrusted code running in the same execution environment.
Entitlements offer a customizable and enforceable model of constness—similar to const or mutable in C++ or Rust—but designed to be more expressive and suitable for the needs of blockchain programming.
Polymorphism and Downcasting - Cadence also improves polymorphism. With interfaces now being strictly about specifying the minimum behavior of a type, developers can downcast references to discover and access additional features on an object dynamically. Entitlements complement this by acting as gates—ensuring that only authorized references can perform sensitive actions.
Conclusion: A Smarter Way to Secure Smart Contracts
With Entitlements, the Cadence smart contract programming language introduces a clean, modern model for managing access and permissions:
- Interfaces define what an object can do.
- Entitlements define what a reference is allowed to do.
- Capabilities are how references are shared and stored.
This new model makes Cadence safer, more flexible, and better suited for complex, real-world smart contracts, especially in adversarial blockchain environments.
Whether you're building a simple NFT or a permissioned DeFi vault, Cadence's new entitlement system gives you the tools to do it right.
Learn more and start building today at developers.flow.com.