Skip to content

FR: Add SPIFFE support #13842

@Radiergummi

Description

@Radiergummi

What are you trying to do?

Tailscale currently handles machine-to-machine communication by encrypting connections and authenticating machines. However, what we actually often want to do is authenticate workloads running on top of the machines in containers, K8s pods across different clouds or data centres.

I'd like to propose integrating support for the SPIFFE Workload API into the Tailscale client. This would bring zero-trust down to the service level, allowing workloads to have cryptographically verifiable identities (SVIDs—certificates or JWTs). These identities could then be used for mutual authentication between services, which would add an extra layer of security in dynamic, distributed environments.

SPIFFE gives us a way to assign identities to services, which can then be used for mutual authentication, without requiring static definitions of which host is talking to which. This makes it a great fit for highly dynamic setups.

In short: I want to be able to issue SPIFFE identities to workloads running on Tailscale nodes where the Tailscale client acts as the Workload API, and issues these identities based on grants defined in the Tailscale UI. Traffic between services could then be signed with the identity certificate automatically, delegating inter-service communication trust to Tailscale. This removes the need for application credentials.

How should we solve this?

I haven't fleshed this out fully, yet. It would work something like this:

The Tailscale API could act as a SPIFFE server. It’s already handling a lot of the same responsibilities (like node registration and attestation), so extending this to handle workload identities seems like a natural fit.
Tailscale Nodes would act as a SPIFFE client, exposing the workload API to services running on the node. The node would provide attestation data and request SPIFFE SVIDs for workloads from the Tailscale API. Again, Tailscale already does a lot of this for machines, so it’s just about extending it to services.

The SPIFFE identities are coupled to a hostname, which ties in wonderfully with the Tailnet. Tailscale could issue these identities based on service configuration defined on the Tailscale servers. Since open ports are already picked up, it would feel natural to be able to decide which of these receive a custom name, and get exposed to the broader Tailnet. In the policies, a new kind of source-destination mapping could be introduced to let services communicate—say:

{
  "action": "accept",
  "src": "service:billing-api@tag:app",
  "dest": "service:postgres@tag:database",
}

(This syntax is just an example, probably bad, and shouldn't be taken at face value)

Now, assuming an application on a node tagged app would receive blessing through an admin to expose as billing-api in the Tailscale Admin UI; that would cause the Tailscale client on the node to request an SVIN for this service from the Tailscale API, and hold it. Once the service starts opening a TCP connection to a node tagged database on a port a service named postgres (in turn blessed by an admin), the Tailscale client could perform automatic, mutual TLS authentication between those two services, and provide assertions to the participating applications. This is very similar to the application layer capabilities Tailscale already supports.
The difference from the current state is that I now don't need to worry about database credentials anymore: When using SVINs, I can rely on Tailscale taking care of authorising connections between services. This fits in very well with the overall product vision, in my opinion.

What is the impact of not solving this?

The impact of not solving this is that Tailscale users who require workload-level identity management for securing their services will need to resort to a combination of ACLs, grants, and application-specific authentication methods. Looking at the list of participants to the SPIFFE specification, I suppose more providers are going to support it in the future, so Tailscale would miss out on a great opportunity to implement a standard application authorisation protocol that fits with the product very well.

Anything else?

I’d recommend checking out the SPIFFE/SPIRE documentation for more details and to get a better idea of how this might fit into Tailscale’s ecosystem.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions