# Databricks AI Functions Unity Catalog permissions are GA

> Revoking EXECUTE on system.ai stops every task-specific AI Function at once. Write the allow-list first, and govern ai_query on its own.

By Preetham Reddy, 27 October 2026. Databricks Field Guide, TechFabric. Canonical: https://databricks.techfabric.com/notes/ai-functions-unity-catalog-permissions-is-now-generally/

A nightly job can call `ai_classify` on the tickets and `ai_parse_document` on the attachments with no grant on either function. By default, all users hold `EXECUTE` on the `system.ai` schema ([how the permissions work](https://docs.databricks.com/aws/en/large-language-models/ai-functions-uc-permissions#how-ai-functions-unity-catalog-permissions-work)). On 27 October 2026 [AI Functions Unity Catalog permissions](https://docs.databricks.com/aws/en/release-notes/product/2026/october#ai-functions-unity-catalog-permissions-is-now-generally-available) became generally available, so a metastore admin can take that grant away. The docs, updated on 26 October, still say the Databricks account team has to enable it, and that every AI Function call stops the moment the schema grant is gone ([AI Functions Unity Catalog permissions](https://docs.databricks.com/aws/en/large-language-models/ai-functions-uc-permissions)). The documented sequence revokes first. It takes `EXECUTE` from All Users, or from all groups, and grants it back per function afterwards ([remove EXECUTE](https://docs.databricks.com/aws/en/large-language-models/ai-functions-uc-permissions#step-1-remove-execute-permission-from-the-schema)). We'd enable it. We would not click revoke while that job can still start.

A function we meant to keep fails in that gap the same way as one we meant to close. So the helper below has to pass before anyone opens Catalog Explorer. It models our check. It is not a Databricks API.

```python
def revoke_window(task_functions, enrollment, runtime_ok):
    """task_functions maps a function name to the group that keeps it.
    enrollment is 'active', 'closed', or None. runtime_ok means 17.3 LTS."""
    if not runtime_ok:
        return "move the jobs to 17.3 LTS first"
    if any(group is None for group in task_functions.values()):
        return "name the group that keeps each function"
    if enrollment is None:
        return "ask whether the older model permissions are still enrolled"
    if enrollment == "active":
        return "grant functions and models, then revoke, with the jobs idle"
    return "grant the functions, then revoke; ai_query stays a separate decision"

assert revoke_window({"ai_classify": "analysts", "ai_parse_document": None}, "closed", True).startswith("name the group")
assert revoke_window({"ai_classify": "analysts"}, None, True).startswith("ask whether")
assert revoke_window({"ai_classify": "analysts"}, "active", True).startswith("grant functions and models")
assert revoke_window({"ai_classify": "analysts"}, "closed", False).startswith("move the jobs")
```

The missing-group assertion is the one a hurried allow-list drops. Leave `ai_parse_document` without a group and that function is refused as soon as the schema grant is gone, and so is `ai_extract` or `ai_summarize` when another job calls it and the map never mentioned it. We'd build the map by reading the jobs.

Unknown enrollment is a different failure. Fold it into "closed" and we would miss an account where this same revoke also stops model calls. `ai_query` is absent from `task_functions` on purpose. The permissions page leaves it out, because it calls a model serving endpoint ([limitations](https://docs.databricks.com/aws/en/large-language-models/ai-functions-uc-permissions#limitations)). The page it points to was updated on 28 September 2026 and applies only to accounts already enrolled in [foundation model Unity Catalog permissions](https://docs.databricks.com/aws/en/machine-learning/foundation-model-apis/model-uc-permissions). On those accounts this same schema revoke stops pay-per-token calls and batch inference (AI Functions) to all models immediately ([how model permissions work](https://docs.databricks.com/aws/en/machine-learning/foundation-model-apis/model-uc-permissions#how-foundation-model-unity-catalog-permissions-work)). New enrollments are closed, and restricting hosted models there means Unity Gateway model APIs. Active enrollment is why the helper adds the model allow-list to the same sitting. Closed enrollment still leaves the tickets classifiable with `ai_query`. That path is a separate decision. [Foundation models](https://databricks.techfabric.com/guide/foundation-models/) already records where Databricks' two pages disagree on whether a permission check applies to it. Spend for that call is recorded in `system.billing.usage`.

`runtime_ok` is there because a job can call the function and still be on the wrong runtime for this control. The call needs Databricks Runtime 15.4 LTS or above, 18.2 recommended, and it is unavailable on a Classic SQL warehouse ([AI Functions](https://docs.databricks.com/aws/en/large-language-models/ai-functions), updated 27 October 2026). The permissions feature asks for 17.3 LTS, with Unity Catalog on the account ([requirements](https://docs.databricks.com/aws/en/large-language-models/ai-functions-uc-permissions#requirements)). We'd move the warehouse, then ask the account team to enable the feature. [Unity Catalog](https://databricks.techfabric.com/guide/unity-catalog/) already treats a function as a securable object. The grant worth the change window is the one on the functions Databricks ships in `system.ai`.

```mermaid When we would revoke EXECUTE on system.ai
flowchart TD
  A["Functions and groups listed"] --> B{"Jobs on runtime 17.3 LTS"}
  B -->|"no"| C["Move the jobs first"]
  B -->|"yes"| D{"Model enrollment known"}
  D -->|"no"| E["Ask the account team"]
  D -->|"active or closed"| F["Grant, then revoke, jobs idle"]
```

> **Our position**: We'd enable this for the classification job only after `revoke_window` returns a grant-then-revoke line: groups named, runtime on 17.3 LTS, enrollment known. The two clicks happen in one sitting, with the job idle. `ai_query` stays off that map. When the older enrollment is closed, we'd restrict hosted models through Unity Gateway model APIs, as that page says.
