issuer field identifies who is accessing the data — the issuer must have been granted access on-chain via FHE.allow(handle, address). When a permit is used, CoFHE validates it against the ACL contract to confirm that the issuer has access to the requested encrypted handle.
Each permit includes a sealing keypair. The public key is sent to CoFHE so it can re-encrypt the data for the permit holder. The private key stays client-side and is used to unseal the returned data.
When do you need a permit?
decryptForView: always requires a permit.decryptForTx: depends on the contract’s ACL policy for thatctHash.- If the policy allows anyone to decrypt, you can use
.withoutPermit(). - If the policy restricts decryption, you must use
.withPermit(...).
- If the policy allows anyone to decrypt, you can use
Prerequisites
Create and connect a client. Permits are scoped to a chainId + account.Quick start
The examples below show two approaches. The
client.permits API is the recommended approach — it automatically signs permits with the connected wallet and manages the permit store. The PermitUtils API is a lower-level alternative that gives you direct control over signing and storage.decryptForView(...).execute()uses the active permit.decryptForTx(...).withPermit().execute()uses the active permit.
Permit types
| Type | Who signs | Use case |
|---|---|---|
self | issuer only | Decrypt your own data (most common) |
sharing | issuer only | A shareable “offer” created by the issuer for a recipient |
recipient | recipient (includes issuer signature) | The imported permit after the recipient signs it |
- Permit
expirationis a unix timestamp in seconds. The default is 7 days from creation. - When a permit is created via
client.permits.*, it is automatically stored and set as the active permit.
Creating a self permit
A self permit lets you decrypt data that was allowed to your address.createSelf
getOrCreateSelfPermit
Returns the active self permit if one exists. Otherwise creates and signs a new one. This is the recommended approach for most applications.Sharing permits
Sharing permits let an issuer delegate their ACL access to a recipient. The recipient can then decrypt the issuer’s data without needing their ownFHE.allow.
Issuer creates a sharing permit
The issuer creates a sharing permit specifying the recipient’s address.
Issuer exports the permit
Export the permit as a JSON blob and share it with the recipient.
The exported JSON does not contain any sensitive data and can be shared via any channel.
Active permit management
The SDK tracks all stored permits and an active permit hash perchainId + account. Creating or importing a permit via client.permits.* automatically stores it and selects it as active.
List stored permits
Read / select the active permit
Removing permits
Persistence and security
- The SDK persists permits in a store keyed by
chainId + account. - In web environments, this store uses
localStorageunder the keycofhesdk-permits. - A stored permit includes the sealing private key. Treat it like a secret.
- Never share serialized permits with other users.
- To share access, use
PermitUtils.export(...)which strips sensitive fields.