SPIFFE Broker Endpoint

This document is part of the SPIFFE standard. The canonical version can be found at https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE_Broker_Endpoint.md

Stability: Incubating - see STABILITY.md.

Status of this Memo

This document specifies an identity endpoint standard for the internet community, and requests discussion and suggestions for improvements. Distribution of this document is unlimited.

Abstract

The SPIFFE Broker Endpoint is a dedicated endpoint for trusted infrastructure components in SPIFFE. It offers specific APIs that are not targeted to workloads but components in the infrastructure that can act on behalf of workloads and request corresponding SVIDs.

Table of Contents

1. Introduction
2. Accessibility
3. Transport
3.1. Transport Security
4. Locating the Endpoint
5. Authentication and Authorization
6. Error Codes
7. Extensibility and Services Rendered

1. Introduction

Workloads today run on a variety of different platforms that each offer unique set of capabilities and limitations. The SPIFFE Workload API offers workloads a standardized way to retrieve SVIDs.

Since the introduction of SPIFFE and its Workload API new patterns have arisen where the workload itself is not requesting the SVID but a component doing it on-behalf-of the workload. This component either provisions the SVID to the workload in a way the workload understands, or, hooks into the network to perform transport layer security such as TLS outside of the workload. Service meshes are well-known for this pattern.

In the beginnings, the on-behalf-of component was a proxy running next to the workload. Each workload would have its own peer-proxy and together they would form a combined security boundary. In this situation, the proxy was able to leverage the SPIFFE Workload Endpoint and API to retrieve SVIDs on behalf of the workload it shares the security boundary with. This pattern is commonly known as the “sidecar pattern”, and the proxy as a “sidecar” or “sidecar proxy”.

Since this has been introduced, the pattern has evolved to locate the proxy from one per workload to one per node for security, separation of concern, maintenance and other reasons. A proxy that acts on-behalf of multiple workloads is referred to as a “broker”. This pattern poses a conflict with the SPIFFE Workload API & Endpoint. The security boundary of the Broker and the workload is different, and thus the component that requests an SVID is not the workload, or a “workload specific” (sidecar) instance anymore but a broker that acts on-behalf of all the workloads running on the node. The SPIFFE of today would see the broker as the workload and not the workload the broker represents.

Another use case for the broker is a node agent placed in front of other, potentially multiple, node agents and routing requests. This can be for functional and non-functional reasons.

The following diagram illustrates the different endpoints and their audiences.

flowchart TD
    Workload
    Broker
    SPIFFE
    workloadendpoint{{SPIFFE Workload Endpoint}}
    brokerendpoint{{SPIFFE Broker Endpoint}}

    Workload<-- SPIFFE Workload API -->workloadendpoint
    Workload<-- SPIFFE Workload API or other means of provisioning (non-SPIFFE, out of scope) -->Broker
    Broker-- SPIFFE Broker API -->brokerendpoint
    brokerendpoint---SPIFFE
    workloadendpoint---SPIFFE

2. Accessibility

The SPIFFE Broker Endpoint can be exposed through a local or a remote endpoint. Depending on the use-case a local endpoint may be sufficient while some deployments require a remote endpoint. Where possible, accessibility SHOULD be restricted to designated clients only and not be available to workloads.

3. Transport

The SPIFFE Broker Endpoint MUST be served over gRPC, and compliant clients MUST support gRPC. It may be exposed as either a Unix Domain Socket (UDS) or a TCP listen socket. For local endpoints the Unix Domain Socket transport is preferred.

As a hardening measure against Server Side Request Forgery (SSRF) attacks, every client request to the SPIFFE Broker Endpoint MUST include the static gRPC metadata key broker.spiffe.io with a value of true (case sensitive). Requests not including this metadata key/value MUST be rejected by the SPIFFE Broker Endpoint (see the Error Codes section for more information). This prevents an attacker from exploiting an SSRF vulnerability to access the SPIFFE Broker Endpoint unless the vulnerability also gives the attacker control over outgoing gRPC metadata.

3.1 Transport Security

The SPIFFE Broker Endpoint requires transport security in the form of mutual TLS. Compared to the SPIFFE Workload Endpoint the broker and the implementation are expected to have a previously established root of trust in the form of SPIFFE bundles and X509-SVIDs. Effectively, this means that both parties need to make use of the SPIFFE Workload API as workloads first, before serving or connecting to the SPIFFE Broker Endpoint. Please see the Authentication and Authorization section for more information.

4. Locating the Endpoint

Clients may be explicitly configured with the socket location, or may utilize the well-known environment variable SPIFFE_BROKER_SOCKET. If not explicitly configured, conforming clients MUST fall back to the environment variable.

The value of the SPIFFE_BROKER_SOCKET environment variable is structured as an RFC 3986 URI. The scheme MUST be set to either unix or tcp, which indicates that the endpoint is served over a Unix Domain Socket or a TCP listen socket, respectively.

If the scheme is set to unix, then the authority component MUST NOT be set, and the path component MUST be set to the absolute path of the SPIFFE Broker Endpoint Unix Domain Socket (e.g. unix:///path/to/endpoint.sock). The scheme and path components are mandatory, and no other component may be set.

If the scheme is set to tcp, then the host component of the authority MUST be set to an IP address or a DNS name, and the port component of the authority MUST be set to the TCP port number of the SPIFFE Broker Endpoint TCP listen socket. The scheme, host, and port components are mandatory, and no other component may be set. As examples, tcp://127.0.0.1:8000 and tcp://broker.example.com:8443 are valid, and tcp://127.0.0.1:8000/foo is not.

DNS names are permitted because the Broker Endpoint is allowed to be served over the network and is authenticated (in contrast to the SPIFFE Workload Endpoint, which is local-only and not authenticated).

5. Authentication and Authorization

The SPIFFE Broker Endpoint requires mutual authentication in the form of Mutual Transport Layer Security as defined in RFC 5246 (TLS 1.2) and RFC 8446 (TLS 1.3) in the form of X509-SVIDs. Prior to the mutual authentication both parties need to retrieve the SVID and bundle, for instance by using the SPIFFE Workload API.

The nature of the SPIFFE Broker Endpoint requires strong access control and only authorized callers must be allowed to connect. Controlling access only by accessibility is highly discouraged and implementers should restrict both, only making the endpoint accessible to allowed components and implementing strict access control on the endpoint. It is recommended to base access control on the SPIFFE-ID of the client. Given the broad capabilities the SPIFFE Broker Endpoint offers to authorized clients the policy is recommended to be static and based on configuration.

In addition, it is required to also perform server authentication on the broker in the form of validating the expected SPIFFE-ID of the SPIFFE provider. This is to prevent man-in-the-middle attacks where an attacker poses as a SPIFFE provider and returns poisoned SVIDs or bundles to a legitimate broker.

6. Error Codes

A number of error conditions may be encountered by the client when interacting with the SPIFFE Broker Endpoint. For instance, the client request may have omitted the mandatory security header (see the Transport section for more information), or the SPIFFE Broker Endpoint implementation may still be initializing or otherwise unavailable.

Implementations receiving a client request that does not contain the mandatory security header MUST respond with gRPC status code “InvalidArgument”. Clients encountering the “InvalidArgument” status code SHOULD NOT retry, as this indicates that an error has been made in the client implementation, and is not recoverable.

In the event that the SPIFFE Broker Endpoint implementation is running but unavailable, for instance if it is still initializing or it is performing load shedding, clients will receive the gRPC status code “Unavailable”. Clients receiving this code OR clients which are unable to reach the SPIFFE Broker Endpoint MAY retry with a backoff.

In situations where the client cannot be identified “Unauthenticated” is returned to clients. Clients should keep in mind that this is unlikely to be observed because authentication errors result in a rejected connection before the gRPC layer is initialized. Retries using the same certificate SHOULD NOT be made, instead clients should turn to the SPIFFE Workload API and refresh their credentials before retrying.

Clients that are not valid brokers and are not authorized are expected to observe “PermissionDenied”. Clients receiving this code MAY retry with a backoff to allow for non-static policy at the server.

As a summary, the expected error codes are:

Code Condition Client Behavior
InvalidArgument The gRPC security header is not present in the client request. Please see the Transport section for more information. Report an error, don’t retry.
Unavailable The SPIFFE Broker Endpoint implementation is unable to handle the request. Retry with a backoff.
Unauthenticated Client cannot be identified. Refresh credentials and retry with a backoff.
PermissionDenied Client is not authorized. Report an error, don’t retry.

API-layer errors related to the workload reference carried in a request (e.g., the referenced workload does not exist or is not entitled to an SVID) are specified in Section 4.8 of the SPIFFE Broker API.

7. Extensibility and Services Rendered

The SPIFFE Broker Endpoint may expose a variety of identity-related services, such as brokering or delegated issuance. Individual services are exposed through the use of the gRPC/Protobuf service primitive. A new (uniquely named) service must be introduced in order to extend the SPIFFE Broker Endpoint.

Since it is the promise of this specification to provide strong portability, the authors feel that allowing extension of existing logical services works against the spirit of SPIFFE. Should additional functionality be rendered by adding endpoints to existing logical services, a portability guarantee cannot be made in the event that a dependent workload moves from one SPIFFE-compliant environment to another. Instead, if use cases are identified that are common across all SPIFFE implementations changes should be made directly in SPIFFE to keep portability high.

While all SPIFFE Broker Endpoint implementations MUST expose the SPIFFE Broker API, it may at times be difficult to know what additional services are supported in a given environment. As a result, endpoint implementers SHOULD include support for gRPC Server Reflection. If a client encounters an endpoint which does not support gRPC Server Reflection, it SHOULD assume that the only available services are those defined in the SPIFFE Broker API.