Concept · ACL

Access control on encrypted state

Every encrypted handle has an ACL list of addresses authorised to decrypt. The list is append-only — no revocation, no rotation. Grant deliberately.

The primitive#

The FHEVM coprocessor maintains a list of (handle, address) tuples. When the SDK asks the relayer to decrypt a handle, the relayer checks: does this caller's signature recover an address that's in the handle's ACL list? If yes, return plaintext. If no, refuse.

The contract grants ACL with FHE.allow(handle, addr) — a single tx call that the SDK wraps inside hooks like useDiscloseToParty, useDiscloseHandleToParty, and (for batches) useBatchDiscloseHandlesToParty.

The append-only rule#

Once granted, an ACL entry can't be revoked. There is no "undo" primitive in FHEVM. If you grant Mira access to her vested amount, Mira can decrypt that handle forever — even if she leaves the company. Vesting positions get split or transferred to rotate the handle in practice, but the original handle remains decryptable by the original recipient.

Granting from your code#

components/DiscloseToAuditor.tsx
tsx
import { useDiscloseToParty, DisclosureType } from "@tokenops/sdk/fhe-vesting/react";

function DiscloseToAuditor({ vestingId }) {
  const disclose = useDiscloseToParty({ address: managerAddress });
  return (
    <button
      onClick={() =>
        disclose.mutate({
          vestingId,
          party: "0xAuditor...",
          disclosureType: DisclosureType.TotalAllocation,
        })
      }
    >
      Grant auditor read access
    </button>
  );
}

useDiscloseToParty grants ACL on exactly ONE encrypted field per call — pass disclosureType: DisclosureType.<variant> (TotalAllocation, SettledAmount, VestedAmount, or ClaimableAmount) to select which field. To grant all four fields (or several vestings) at once, use useBatchDiscloseToParty with one DisclosureType per entry. For one-off disclosure of an arbitrary handle, use useDiscloseHandleToParty with a specific handle.

Operators#

ERC-7984 has a sibling primitive called operators — addresses authorised to call confidentialTransferFrom on an account's behalf. Operators are separate from ACL: they're an ERC-7984 token primitive, not an FHEVM one. The SDK wraps both — check setOperator, useApproveTokenOnWallets (disperse), and the disperse story's chapter 1 walkthrough.

See also