---
title: Granting functions
description: "Grant a package to an agent: version, timeout, network, and approvals."
---

A package does nothing until an agent version **grants** it. The grant is where every decision about a call lives: the package does not declare its own network, credentials, or limits, so the same package can be granted narrowly to one agent and broadly to another.

In the console, grants are under **Tools** › **Function packages** in the [version editor](/console/agents#function-packages). In an [agent config](/reference/agent-config) they are the `functions` array.

![A function package grant in the version editor](/blume-assets/content/docs/_images/en/agent-editor-functions.webp)

## The fields

| Console | Config | What it sets |
| --- | --- | --- |
| **Package from** | `source.type` | `platform` for a package Subako ships, `workspace` for one this workspace uploaded. |
| **Package** | `source.package` / `source.function_id` | Which package: a platform package by name, a workspace package by its ID. |
| **Version** | `source.version` | `{"type": "latest"}` or `{"type": "pinned", "number": 3}`. Platform packages always run the version the deployment ships. |
| **Name** | `name` | The grant's name. Defaults to the package's. Lowercase letters, digits, and `-`, up to 32 characters, unique among the version's grants. |
| **Timeout (seconds)** | `timeout_secs` | How long one call may run: 1 to 300 seconds, 60 when empty. |
| **Network** | `network` | Which hosts its HTTP requests may reach. |
| **Credentials** | `http_credentials` | Origins whose vault credential is attached to requests sent there. |
| **Default policy**, **Tool rules** | `default_policy`, `tools` | Whether a call runs, asks first, or is refused. |

```json agent.json
{
  "functions": [
    {
      "name": "files",
      "source": { "type": "platform", "package": "files" },
      "default_policy": "allow"
    },
    {
      "name": "billing",
      "source": {
        "type": "workspace",
        "function_id": "0192f5c4-7a1e-7d3c-9b8f-2c6d1e4a5b70",
        "version": { "type": "pinned", "number": 3 }
      },
      "default_policy": "allow",
      "tools": [{ "name": "issue_refund", "policy": "require_approval" }],
      "timeout_secs": 120,
      "network": { "type": "allowlist", "hosts": ["billing.acme.example"] },
      "http_credentials": ["https://billing.acme.example"]
    }
  ],
  "volume": { "data": { "type": "enabled" } }
}
```

## What the model sees

Each tool reaches the model as `fn__<grant>__<tool>` — `fn__billing__issue_refund` above — with the tool's description and input schema. The package's own description, and a tool's output schema, are for people, not the model.

Subako also tells the model, once per grant, how the Session Volume is laid out, how long a call may run, and which hosts it reaches, so the grant itself steers how the agent uses it.

## Versions

A session resolves every grant to one version when it starts, and keeps it to the end:

- **Latest** follows the package: a version pushed today is what sessions started from now on run, with no new agent version needed.
- **Pinned** stays on one version until a new agent version names another.

Pin a package whose changes you want to review in an agent version, and follow the latest for one you trust to move on its own.

## Network

A call has no network unless its grant gives it one.

| Console | Config | Requests may reach |
| --- | --- | --- |
| **No network** | `{"type": "none"}` | Nothing. The default. |
| **Any public host** | `{"type": "unrestricted"}` | Any public host. |
| **Only allowed hosts** | `{"type": "allowlist", "hosts": [...]}` | Only the hosts listed, up to 64. |

A host is a name like `api.example.com`, which admits that host alone, or `*.example.com`, which admits its subdomains but not `example.com` itself. Whatever the grant says, requests go over `https` only, and private, reserved, and metadata addresses are always refused — including after a redirect, which is checked hop by hop.

## Credentials

A function that calls an authenticated API should never hold its key. Instead:

1. Add the key to a [vault](/console/vaults) as an **HTTP headers** credential for the API's origin — `https://billing.acme.example`, with an `authorization` header.
2. Name that origin under the grant's **Credentials** (`http_credentials`, up to 16). It must also be reachable under the grant's network.
3. Start the session with that vault.

Every request the function sends to that origin then carries the headers, added after the request leaves the module. [Calling APIs](/functions/calling-apis) walks through it with GitHub. The module never sees them, and a module that tries to set one of those headers itself is refused. If none of the session's vaults hold a credential for the origin, the request goes without one.

## Approvals

Each grant has a **Default policy** for its tools, and **Tool rules** to override it by exact tool name:

- **Allow** (`allow`) — the call runs.
- **Ask first** (`require_approval`) — the call waits for a person to allow or deny it, in the console or [from your app](/build/approvals-and-forms).
- **Deny** (`deny`) — the tool is not offered to the model.

A package that only reads can run on **Allow**, with **Ask first** on the one tool that changes something. A tool the model may retry after a timeout should be safe to run twice.

## The Session Volume

The agent config's `volume` — **Session Volume** in the editor — decides whether functions get the **Data** area as well as **Temporary**. See [the runtime](/functions/runtime#the-session-volume).

## Billing

A function call is billed for the time it runs, waiting on HTTP included — 0.01 SC a second on Subako Cloud — and the bytes it writes to the volume. See [Plan and usage](/console/plan-and-usage#what-is-billed).
