Skip to content
Thyme Docs

Function Permissions

SDK 0.8.0 and CLI 0.10.0 support an optional functions/<task>/permissions.json. The file declares the EVM target and function-selector pairs used by a release. It is packaged with the code, so its contents are covered by the release checksum and immutable version tag.

functions/token-task/permissions.json
{
  "calls": [
    {
      "target": { "arg": "tokenAddress" },
      "function": "transfer(address,uint256)"
    },
    {
      "target": { "11155111": "0x1111111111111111111111111111111111111111" },
      "function": "0x095ea7b3"
    }
  ]
}

The fixed address above is a placeholder: replace it with the intended contract on that chain. thyme new does not create this optional file.

File contract

Field or limitRule
Top levelAn object with exactly calls; do not include a version field.
callsArray of entries with exactly target and function.
Argument target{ "arg": "tokenAddress" } refers to a top-level argument. The name matches ^[A-Za-z_][A-Za-z0-9_]*$.
Fixed targetA nonempty mapping from positive decimal chain IDs to valid EVM addresses.
functionABI function signature such as approve(address,uint256), or exactly four bytes as 0x plus eight hex characters.
File sizeAt most 16 KiB of UTF-8 JSON.
Call countAt most 50 entries after deduplication by target declaration and selector.

Unknown fields are errors. Addresses are checksummed and selectors normalized. Argument targets cannot use nested paths, and a target cannot combine arg with chain mappings.

{ "calls": [] } explicitly declares no calls. Omitting the file means the release has no permission declaration; that is different from an empty declaration.

Resolution and enforcement

Argument targets resolve against executable args. Fixed targets resolve against the executable chain; every declared target must resolve. A returned call is matched using its address and the first four bytes of calldata. Empty calldata has no selector and cannot match a rule.

The declaration does not constrain calldata argument values. For example, declaring transfer(address,uint256) does not restrict the transfer recipient or amount. It also does not by itself grant a Safe module permission or replace a profile's on-chain authorization.

thyme upload rejects invalid manifests, including in CI and with --yes. The backend independently validates the archive. In the cloud, calls outside a declared manifest are rejected before submission. See Flow permission enforcement for profile compatibility and migration behavior.

Local verification

The local checker resolves argument targets from raw args.json, and obtains the chain ID from RPC_URL when fixed targets are present. Undeclared or unresolved calls produce warnings rather than blocking local execution. Ensure an argument used as a target is explicitly present in args.json; the checker does not apply Zod defaults or transforms to it.

For current local-run limitations, see thyme run. A successful local process exit is not proof of cloud permission compatibility.

Release changes

Changing the manifest changes the archive checksum. Upload a new immutable tag, review the new permissions, then switch a paused executable to that release. Args changes can also change resolved addresses for argument targets and may require renewed profile authorization.

The SDK's archive utilities carry the raw manifest text; they do not validate it. Archive integrators must validate the extracted text before trusting a declaration.