Centralize LLM access and spending

Last validated:

Aperture by Tailscale is currently in beta.

When developers and AI coding agents each use their own LLM API keys, organizations lose visibility into who is using which models, how much they are spending, and what data they are sending to providers. Keys get shared across teams, embedded in CI/CD pipelines, and stored on developer laptops where they are difficult to rotate or revoke.

Aperture by Tailscale acts as a centralized gateway between your LLM clients and upstream providers. You store API keys in one place, grant model access per user or team, and get per-user usage tracking and session logs without changing how developers use their tools.

Create your Aperture instance

  1. Sign up at aperture.tailscale.com and follow the guided setup. After setup completes, Aperture appears as a device named ai in your tailnet.

    For detailed setup instructions, refer to get started with Aperture.

  2. Open the Aperture dashboard at http://ai/ui and go to the Settings page.

  3. Add your LLM provider API keys so Aperture can forward requests on behalf of your users.

    The following example configures Aperture with both OpenAI and Anthropic providers:

    {
    "providers": {
        "openai": {
        "baseurl": "https://api.openai.com",
        "apikey": "YOUR_OPENAI_KEY",
        "models": ["gpt-4.1", "gpt-4.1-mini"],
        "compatibility": { "openai_chat": true }
        },
        "anthropic": {
        "baseurl": "https://api.anthropic.com",
        "apikey": "YOUR_ANTHROPIC_KEY",
        "authorization": "x-api-key",
        "models": ["claude-sonnet-4-5", "claude-opus-4-5"],
        "compatibility": { "anthropic_messages": true }
        }
    }
    }
    

    Developers never access or handle provider credentials. When a client sends a request specifying a model name, Aperture routes it to the correct provider and injects authentication automatically.

    For the full list of supported providers and configuration options, refer to the Aperture configuration reference and the provider compatibility reference.

Grant users access to models

Aperture is deny-by-default: no user can access any model until you explicitly grant access. Use the grants section to control which users or groups can access which models.

Configure grants in the Aperture dashboard or in your tailnet policy file.

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

The following example uses the tailnet policy file to grant your ML engineering team access to all models and give admins full control:

"grants": [
  {
    "src": ["group:ml-engineers"],
    "dst": ["tag:aperture"],
    "app": {
      "tailscale.com/cap/aperture": [
        { "role": "user" },
        { "models": "**" }
      ]
    }
  },
  {
    "src": ["autogroup:admin"],
    "dst": ["tag:aperture"],
    "app": {
      "tailscale.com/cap/aperture": [
        { "role": "admin" },
        { "models": "**" }
      ]
    }
  }
]

You can restrict access to specific models by replacing "**" with a model name pattern in provider/model format. For example, "models": "anthropic/claude-*" grants access to all Anthropic Claude models but no others.

For step-by-step instructions on granting access, refer to grant model access.

Configure AI tools and CI/CD pipelines

Point each LLM client at Aperture instead of the provider directly. Aperture identifies requests by Tailscale device identity, not by API key, so clients use a placeholder key value.

To avoid unexpected TLS issues, use http:// for the Aperture URL when configuring LLM clients. All connections remain encrypted using WireGuard, even when HTTPS is not used.

Claude Code

Create or edit ~/.claude/settings.json:

{
  "apiKeyHelper": "echo '-'",
  "env": {
    "ANTHROPIC_BASE_URL": "http://ai"
  }
}

The apiKeyHelper returns a placeholder because Aperture injects credentials automatically. For additional configuration options (Bedrock, Vertex AI), refer to use Claude Code with Aperture.

CI/CD pipelines

For CI/CD environments such as GitHub Actions, set environment variables in your workflow:

env:
  ANTHROPIC_BASE_URL: http://ai
  ANTHROPIC_API_KEY: "-"

The CI runner must be in the tailnet for this to work. Use the Tailscale GitHub Action to connect runners as ephemeral nodes, or use ts-unplug for environments where installing Tailscale is not possible.

Other LLM clients

Any LLM client that supports a custom base URL can use Aperture. Set the base URL to http://ai and use a placeholder API key. For configuration guides for other tools, refer to set up LLM clients.

Monitor usage and review logs

After traffic flows through Aperture, open the dashboard at http://ai/ui to:

  • Track per-user token usage and cost across all models and providers.
  • Review session logs with request and response details.
  • Audit tool calls made by AI agents to understand what actions agents take on behalf of users.

Aperture attributes each request to the Tailscale identity of the user or device that sent it, giving you real-time visibility into how your organization uses LLMs.

For details on the dashboard and available metrics, refer to the Aperture dashboard reference.