# Model access

> Decide which models your organization, each team, each person and each service key may use, with allow and deny lists that only ever narrow.

Product: AI Cost Optimizer Gateway (ACOG). Web version: https://tessarac.com/docs/acog/govern/model-access. Last updated: 2026-10-16.

Your connections decide which models exist for your organization. Model access decides who may use them.

## How rules stack

A rule can be set at four levels:

| Level | Applies to |
|---|---|
| Organization | Every request |
| Team | Requests attributed to members of the team |
| Person | Requests made with that person's keys |
| Service key | Requests made with that one service key |

The organization sets the ceiling, a team can only narrow it, a person narrows it further, and a single service key can be pinned tighter still. If any level blocks a model, the request is blocked: a narrower level can never re-allow what a broader one denied.

Each rule is one of:

| Mode | Effect |
|---|---|
| **Allow only these models** | Every model not listed is refused at this level |
| **Deny these models** | Listed models are refused at this level |

## Setting rules

Model access lists are on **Admin → Providers**. Viewing them is open to provider admins; changing them requires the **Set spend budgets, rate limits, model access, and guardrails** permission (`admin:budgets`). Changes apply from the next request.

## What a refused request gets

```json
{
  "error": {
    "type": "model_not_allowed",
    "message": "…",
    "scope": "team"
  }
}
```

The status is `403`. `scope` names the level that refused (`org`, `team`, `user` or `service-key`), and the message names the model; the allowed list itself is not disclosed to the caller. Refusals appear on the **Activity** page and can be delivered as the `governance.model_access_denied` [webhook](https://tessarac.com/docs/acog/administer/webhooks.md) event.

On a [native route](https://tessarac.com/docs/acog/api/native-routes.md), if a rule restricts models and ACOG cannot tell which model the request is for (an opaque or multipart body), the request is refused with `403 model_unverifiable` rather than let through.

## With auto mode and fallbacks

Model access applies to the model that will actually answer, including the model auto mode resolves `auto` to. The policy-block fallback is not used when its model is not allowed.

`GET /v1/models` lists every declared model and does not apply model access, so it can list models a rule would refuse for that key.
