Download the PHP package geocodio/laravel-tailscale-identity without Composer

On this page you can find all versions of the php package geocodio/laravel-tailscale-identity. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-tailscale-identity

Tailscale identity for Laravel

Latest Version on Packagist GitHub Tests Action Status Total Downloads

Authenticate internal Laravel apps with your Tailscale tailnet instead of passwords: the tailnet answers who is connecting, and a Tailscale grant (app capability) answers what they may do — both defined in your tailnet policy file, reviewed like any other code.

The package resolves the connecting peer's address with tailscale whois, applies a strict set of rejections, and hands your app a TailscaleIdentity value object: email, display name, node name, peer address, and the raw capability values from your policy's grants. No password, no session to steal, no user admin UI to build. Removing someone from the tailnet (or the grant) removes their access.

It is intentionally small and fail-closed. It does not touch your user model, define roles, or render error pages — your app decides what a capability value means.

Deployment requirements — read this before installing

The security model is the network binding, not this code. Identity is derived from REMOTE_ADDR, so your deployment must guarantee that REMOTE_ADDR is the genuine tailnet peer address by the time PHP sees the request. Four requirements, each of which silently breaks authentication if missed:

  1. The tailnet-facing proxy is the only listener on the Tailscale interface, and it always overwrites X-Real-IP. Never append, never trust the inbound value.
  2. The app-side server trusts X-Real-IP from exactly one place — the loopback (or private) address that proxy connects from. Nothing else may set it.
  3. /var/run/tailscale is mounted into the app container (if you use containers). Host networking does not expose unix sockets — that is a mount namespace, not a network namespace.
  4. The tailscale CLI is present in the app image. No daemon runs in-container; the CLI only talks to the mounted socket.

A worked two-tier nginx example:

[!WARNING] If you cannot guarantee that exactly one proxy sets X-Real-IP and nothing else can, do not use this package.

What this package cannot protect against

An over-broad set_real_ip_from. If your app-side server trusts X-Real-IP from anything but the single proxy that always overwrites it, a tailnet member can present another member's address; whois will confirm that member, and the address check will pass. That is a deployment property, not a code property. The tailscale-identity:verify-topology command exists to make the checkable parts checkable:

It asserts the tailscale CLI is present, the LocalAPI socket is reachable, the node's addresses fall inside Tailscale's ranges, and Laravel's trusted-proxy configuration is not wildcarded. Run it as a deploy smoke test.

Installation

Set your capability name in .env:

Granting access in your tailnet policy

Access is granted with an app capability grant in your tailnet policy file. Grants coexist with legacy ACLs, so no migration is needed:

The capability name is a namespaced string you choose (conventionally a domain you control). The values ({"role": "admin"}) are arbitrary JSON objects — this package returns them as data and never interprets them. No capability means no access (403): the grant is the access gate, so there is no in-app role admin to build or drift out of sync.

Usage

Middleware

tailscale.identity resolves the peer and exposes the identity; it returns 403 for any rejection and 503 when the lookup infrastructure fails (never anonymous access). It deliberately does not log anyone into Laravel's auth system — read the identity and decide yourself:

A typical app layers just-in-time provisioning on top in its own middleware:

Someone in two groups receives two capability objects. Reducing them to one effective role needs an ordering only your app can know — do it where you map capabilities to your role enum.

Rejections

Every check fails closed. A request is rejected (403) when:

An unreachable tailscaled or failing CLI is a 503, never anonymous access.

Local development and testing

The fake driver serves a configured identity without a tailnet. A boot guard refuses to start the app if it is active outside local/testing environments:

Caching

Lookups are cached per address for 60 seconds by default (TAILSCALE_IDENTITY_CACHE_TTL). The cache stores the parsed fields as a plain array — never the DTO: Laravel defaults cache.serializable_classes to false, under which any object read back from a serializing store (like Redis) returns __PHP_Incomplete_Class. Caching an identity object works exactly once per address and then errors for the rest of the TTL; this package does not do that, and the versioned key prefix means upgrades never read old-shape entries.

Why whois and not Tailscale Serve's identity headers?

Serve injects Tailscale-User-Login headers with no subprocess or socket mount — but Serve must terminate the connection to identify the peer, and it can only terminate on a <device>.<tailnet>.ts.net name. If you want your own hostname and certificate, identity has to come out-of-band from the peer address, which is what this package does. whois also returns the full node record, enabling the tagged-node and subnet-router rejections the headers cannot express.

A header-based driver for Serve deployments is out of scope for v1; the IdentityDriver interface is the seam where one would slot in.

Testing

Changelog

Please see CHANGELOG for more information on what has changed recently.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.


All versions of laravel-tailscale-identity with dependencies

PHP Build Version
Package Version
Requires php Version ^8.4
spatie/laravel-package-tools Version ^1.16
illuminate/contracts Version ^11.0||^12.0||^13.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package geocodio/laravel-tailscale-identity contains the following files

Loading the files please wait ...