docs/solidity-guides/acl/README.md
This document describes the Access Control List (ACL) system in FHEVM, a core feature that governs access to encrypted data. The ACL ensures that only authorized accounts or contracts can interact with specific ciphertexts, preserving confidentiality while enabling composable smart contracts. This overview provides a high-level understanding of what the ACL is, why it's essential, and how it works.
The ACL is a permission management system designed to control who can access, compute on, or decrypt encrypted values in fhevm. By defining and enforcing these permissions, the ACL ensures that encrypted data remains secure while still being usable within authorized contexts.
Encrypted data in FHEVM is entirely confidential, meaning that without proper access control, even the contract holding the ciphertext cannot interact with it. The ACL enables:
FHE.allow(ciphertext, address).FHE.allowTransient(ciphertext, address).FHE.makePubliclyDecryptable(ciphertext).Syntactic sugar:
FHE.allowThis(ciphertext) is shorthand for FHE.allow(ciphertext, address(this)). It authorizes the current contract to reuse a ciphertext handle in future transactions.| Allowance type | Purpose | Storage type | Use case |
|---|---|---|---|
| Transient | Temporary access during a transaction. | Transient storage (EIP-1153) | Calling external functions or computations with ciphertexts. Use when wanting to save on gas costs. |
| Permanent | Long-term access across multiple transactions. | Dedicated contract storage | Persistent ciphertexts for contracts or users requiring ongoing access. |
Developers can use functions like allow, allowThis, and allowTransient to grant permissions:
allow: Grants permanent access to an address.allowThis: Grants the current contract access to manipulate the ciphertext.allowTransient: Grants temporary access to an address for the current transaction.makePubliclyDecryptable: Grants permanent, global permission for any entity to decrypt the cleartext value associated with the given ciphertext (handle) off-chain.To check if an entity has permission to access a ciphertext, use functions like isAllowed or isSenderAllowed:
isAllowed: Verifies if a specific address has permission.isSenderAllowed: Simplifies checks for the current transaction sender.isPubliclyDecryptable: Verifies whether any entity is permitted to retrieve the ciphertext's cleartext value off-chain.checkSignatures: Verifies the authenticity of a cleartext value by checking cryptographic signatures. This ensures that the value submitted back to the chain originated from a legitimate public decryption operation on the associated ciphertext handle.isAccountDenied: Checks whether an account is on the deny list. Denied accounts are blocked from allow* calls inside the ACL contract, so they cannot grant or receive new permissions on encrypted values.The ACL supports delegating user decryption rights from one account to another (for example, a backend service or relayer). The delegator is whichever account calls into the ACL — an EOA when calling IACL.delegateForUserDecryption directly, or address(this) when a contract uses the FHE.delegateUserDecryption helper. The two patterns are not interchangeable.
delegateUserDecryption: Grants a delegate the right to user-decrypt on behalf of the caller contract for a specific contractAddress, with an expiration date.delegateUserDecryptionWithoutExpiration: Same as above, but without an expiration date.revokeUserDecryptionDelegation: Revokes a previously granted delegation.isUserDecryptable: Checks if a handle can be decrypted by a user in the context of a specific contract.For the EOA-side flow, the full constraints, and worked examples, see User decryption delegation. For the API reference, see FHEVM API reference.
For a detailed explanation of the ACL's functionality, including code examples and advanced configurations, see ACL examples.