Grant access to models
Aperture denies model requests that do not match a grant. However, the configuration shipped with a new Aperture gateway grants all users access to all models. Allow network access to Aperture through your tailnet, then narrow or replace the default grant to control which models each user or group can use.
For more information on how Aperture uses Tailscale identity for authentication and access control, refer to How Aperture works. For the model behind grants, including deny-by-default access and precedence, refer to how Aperture grants work.
Prerequisites
Before you begin, you need:
- An Aperture gateway with at least one configured provider.
- Admin access to the Aperture dashboard.
- Access to the Tailscale admin console.
Step 1: Allow network access to the Aperture device
Your tailnet access control rules must allow users to reach the Aperture device before they can access models.
- Sign in to the Tailscale admin console.
- Go to the Access controls page.
- Confirm that your access control rules allow users to connect to the Aperture device.
The following tailnet policy file example permits all users in group:ai-users to connect to the Aperture gateway with the hostname ai:
{
"groups": {
"group:ai-users": [
"dave@example.com",
"alice@example.com"
]
},
"hosts": {
"ai": "<aperture-ip-address>"
},
"grants": [
{
"src": ["group:ai-users"],
"dst": ["ai"],
"ip": ["tcp:80", "tcp:443", "icmp:*"]
}
]
}
Replace <aperture-ip-address> with the Tailscale IP address of your Aperture device.
You can also use Tailscale tags to manage access to the Aperture gateway. Assign a tag (for example, tag:ai) to the Aperture device and use it as the dst in your grant rule. For how the Aperture device is referenced in grants defined in the tailnet policy file, refer to Grants versus tailnet policy file grants.
Step 2: Configure grants to control model access
After users can reach the Aperture device, configure grants to define which models they can access. You can define these grants in the Aperture configuration or in the tailnet policy file. Aperture combines matching grants from both sources.
Open the Aperture dashboard and go to Administration > Grants.
Use the visual grant editor, or edit the same grants as JSON on the Administration > Configuration page.
To change the configuration programmatically, refer to the grants configuration reference.
The following example grants all users standard user access and lets them use all Anthropic models:
{
"grants": [
{
"src": ["*"],
"app": {
"tailscale.com/cap/aperture": [
{ "role": "user" },
{ "models": "anthropic/**" }
]
}
}
]
}
To restrict access, replace "*" with individual login names (for example, "alice@example.com"), Tailscale or SCIM groups (for example, "group:ai-users"), or tags (for example, "tag:ci"). Use a tag to grant access to non-user devices such as CI runners or services. Group matching requires visible groups enabled for the Aperture device.
aperture@tailscale.com to enable it.The following example grants members of group:ai-users access to all Anthropic models:
{
"grants": [
{
"src": ["group:ai-users"],
"app": {
"tailscale.com/cap/aperture": [
{ "role": "user" },
{ "models": "anthropic/**" }
]
}
}
]
}
The grant examples on this page use Aperture configuration syntax, where the dst field is not required because the destination is the Aperture device itself. If you define grants in the tailnet policy file instead, you must include a dst key specifying the Aperture device (for example, "dst": ["tag:aperture"]). Omitting dst in a tailnet policy file grant causes the grant to silently have no effect. For a full comparison and conversion steps, refer to Aperture grants vs. tailnet policy file grants.
Each capability entry under tailscale.com/cap/aperture has these fields:
role: Required. Set to"user"for standard access or"admin"for administrative access. Without arolegrant, users receive HTTP 403 responses even if they have model grants.models: Optional. A glob pattern that specifies which models the user can access, inprovider/modelformat. For example,"anthropic/**"matches all Anthropic models, and"**"matches all models from all providers. An entry with nomodelsfield is floating. It applies regardless of model, and it grants no model access on its own.connectors: Optional. An array of FQN globs that grant access to MCP tools, resources, and HTTP connector proxies. Because Aperture is deny-by-default, users have no connector access until an entry matches. Refer to grant MCP tool access for details.
Model pattern examples
The following examples show how to use patterns to grant access to specific models:
| Pattern | Matches |
|---|---|
"**" | All models from all providers |
"anthropic/**" | All Anthropic models |
"openai/gpt-5.5" | Exactly openai/gpt-5.5 |
"*/claude-sonnet*" | Any claude-sonnet* model from any single provider |
Verify access
After configuring grants, verify that users can access the expected models.
-
Connect a test device to your tailnet.
-
Send a request to Aperture with
curlor any HTTP client. Use a model ID that matches a configured provider and yourmodelsgrant. Specify either the bare model name, for example,claude-sonnet-4-6, or the fullprovider/modelform:curl -s http://<aperture-hostname>/v1/messages \ -H "Content-Type: application/json" \ -d '{ "model": "claude-sonnet-4-6", "max_tokens": 25, "messages": [{"role": "user", "content": "respond with: hello"}] }' -
Confirm that the request returns a successful response, which means the grant is working.
If the request fails, use the status code to identify the cause:
- HTTP 403: The user has no
rolegrant. Add a{ "role": "user" }entry. - HTTP 404: The user has a role, but no
modelsgrant matches the requested model, or the model is not configured on any provider. Check themodelspattern and confirm the model ID matches a configured provider.
Refer to Troubleshooting Aperture for help diagnosing access issues.
Next steps
- Grant access to connectors to control which MCP tools, resources, and HTTP APIs users can access.
- Set per-user spending limits to manage costs.
- Set up the chat UI to let users talk to models directly from their browser.
- Set up LLM clients to connect through Aperture.