Handlers

Capabilities & governance

How a handler is granted the right to reach beyond ordinary reads and writes.

Most of the Handler SDK is available to every handler. A handful of methods reach further than ordinary data access, and those require an explicit capability on that specific handler.

CapabilityCovers
sdk:read · sdk:write · sdk:transactionOrdinary data access. Granted to every handler.
sdk:deleteDeleting rows
sdk:queryRaw SQL
sdk:query_ddlSchema changes (implies sdk:query)
sdk:shared_readReading across organizations
sdk:external_emailSending email
sdk:external_stripeStripe calls
sdk:importCSV import

The SDK reference badges every method that needs one.

Checked three times, on purpose

At save

A handler using an ungranted capability is rejected — you find out while writing it, not in production.

At publish

The granted set is frozen into that version's manifest. The version records what it was allowed to do at the moment it shipped.

At runtime

The frozen manifest is enforced on every execution.

Freezing at publish is what makes the grant meaningful. Without it, a capability change would silently alter the behaviour of already-shipped versions, and "what could this version do" would have no answer.

Who can grant

Granting a capability is a privileged act, and the acting principal must hold the capability themselves — an author cannot grant their handler something they do not have. Attempting it returns SDK_CAP_NOT_GRANTED with the specific missing capabilities listed.

Practical advice

Grant the narrowest set that works. If a handler needs sdk:query for one query, ask whether that query could be sdk.readList instead — most can. A handler with no elevated capability is one you never have to think about again.

Next

On this page