Control model access

Last validated:

Aperture by Tailscale is currently in alpha.

Aperture is deny-by-default. Without grants, users can connect to the Aperture device but cannot access any models. This guide covers how to configure network access to Aperture and set up grants that 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.

Prerequisites

Before you begin, ensure you have the following:

Step 1: Allow network access to the Aperture device

Before users can access models, they need network connectivity to the Aperture device through your tailnet.

  1. Sign in to the Tailscale admin console.
  2. Go to the Access controls page.
  3. Confirm that your access control rules allow users to connect to the Aperture device.

The following example permits all users in group:ai-users to connect to the Aperture instance with the hostname ai:

{
  "groups": {
    "group:ai-users": [
      "dave@example.com",
      "alice@example.com"
    ]
  },
  "hosts": {
    "ai": "<YOUR_APERTURE_IP_ADDRESS>"
  },
  "grants": [
    {
      "src": ["group:ai-users"],
      "dst": ["ai"],
      "ip": ["tcp:80", "tcp:443", "icmp:*"]
    }
  ]
}

Replace <YOUR_APERTURE_IP_ADDRESS> with the Tailscale IP address of your Aperture device.

You can also use Tailscale tags to manage access to the Aperture instance. Assign a tag (for example, tag:ai) to the Aperture device and use it as the dst in your grant rule.

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 configure grants in the Aperture dashboard or in your tailnet policy file.

In the Aperture dashboard: Open the Settings page and use the Visual editor or the JSON editor.

In the tailnet policy file: Add grants with tailscale.com/cap/aperture capabilities. This approach lets you use Tailscale groups and tags. Refer to the grants configuration reference for the full syntax.

The following example grants all users standard user access and allows them to use all Anthropic models. This example uses the Aperture configuration format:

{
  "grants": [
    {
      "src": ["*"],
      "app": {
        "tailscale.com/cap/aperture": [
          { "role": "user" },
          { "models": "anthropic/**" }
        ]
      }
    }
  ]
}

To restrict access to specific users, replace "*" with individual login names (for example, "alice@example.com").

If you use the tailnet policy file instead, you can match on Tailscale groups and tags. The following example grants members of group:ai-users access to all Anthropic models:

{
  "grants": [
    {
      "src": ["group:ai-users"],
      "dst": ["tag:aperture"],
      "app": {
        "tailscale.com/cap/aperture": [
          { "role": "user" },
          { "models": "anthropic/**" }
        ]
      }
    }
  ]
}

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 a role grant, users receive HTTP 403 responses even if they have model grants.
  • models: A glob pattern that specifies which models the user can access, in provider/model format. For example, "anthropic/**" matches all Anthropic models, and "**" matches all models from all providers.

Model pattern examples

The following examples show how to use patterns to grant access to specific models:

PatternMatches
"**"All models from all providers
"anthropic/**"All Anthropic models
"openai/gpt-5"Exactly openai/gpt-5
"*/claude-sonnet*"Any claude-sonnet* model from any single provider

Groups (for example, group:engineering) are only available in grants specified in the tailnet policy file. The Aperture configuration can only match on individual login names or tags.

Verify access

After configuring grants, verify that users can access the expected models. Send a test request from a device connected to the tailnet. You can do this with curl or any HTTP client. For example:

curl -s http://ai/v1/messages \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-20250514",
    "max_tokens": 25,
    "messages": [{"role": "user", "content": "respond with: hello"}]
  }'

If the request returns a successful response, the grant is working. If you receive an HTTP 403 error, check that the user has both a role grant and a matching models grant. Refer to Troubleshooting Aperture for help diagnosing access issues.

Next steps