Skip to content

Customizing SPIFFE ID format if using an external SPIFFE-compliant SDS should be supported #43105

@bleggett

Description

@bleggett

Summary

  1. When using the default Istio SDS, the current SPIFFE ID format should be the default
  2. If using an alternative SPIFFE-compliant SDS, using an alternative SPIFFE ID format should be allowed without having to resort to DestRule hacks
  3. Other parts of Istio should actively avoid introducing unnecessary implicit assumptions about the SPIFFE ID format and what is minting them to avoid creating more de-facto restrictions around their use, format, and the level of attestation a given user-supplied SPIFFE-compliant SDS server is actually configured for.

Detail

Currently, Istio uses a nonstandard variant of the SPIFFE ID spec, that mandates a SPIFFE ID format in the URI SAN field of the x509 workload certs:

spiffe://<trust_domain>/ns/<workload_namespace>/sa/<workload_service_account>

This means that workload certs minted by the default Istio SDS are indistinguishable - if I have 5 pods under the same service account, they share the same credentials, even if they may have different containers, run on different nodes, etc etc.

That is because the default Istio SDS is simplistic, does no granular workload identity attestation, and merely passes through trust and workload identity to K8S service accounts, which is Good Enough Most Of The Time.

Now that Istio supports replacing the default SDS provider with alternative SPIFFE-compliant SDS servers, such as SPIRE, this restriction makes less sense - the SDS server does (and should) control the format of the SPIFFE ID, and the granularity of the workload identity - for instance, if I use SPIRE with Istio and want to do workload attestation beyond just the service account level, I can easily do that today, and the SPIFFE ID format is defined with SPIRE, not Istio.

In fact, it is perfectly possible to do this today - I can integrate SPIRE with Istio as per our current docs, and configure SPIRE to mint SPIFFE IDs in a non-Istio-standard format, appending more granularity to the SPIFFE identifier to suit the level of attestation granularity my SPIFFE authority is actually engaging in:

spiffe://<trust_domain>/ns/<workload_namespace>/sa/<workload_service_account>/nodeid/<node_id/wl/<workload_name> - for instance

This works just fine with Istio, with the following exception - SPIFFE SAN validation is a hardcoded Envoy config that requires an exact match on spiffe://<trust_domain>/ns/<workload_namespace>/sa/<workload_service_account> - even though other forms of matching for SANs are supported by Envoy, we do not support them or expose them as configurable options.

This can be worked around with a DestinationRule such as the following:

# TODO destination rules need to be created for any SPIFFE IDs that don't follow the
# format that Istio expects (ns/NAMESPACE/sa/TARGET_POD_SVC_ACCOUNT)
# because ATM Istio defaults to clientside SAN checks that assume that SPIFFE ID format
# and this is not currently configurable
#
# Additionally, since DestinationRules override Istio's "default automTLS" settings, we need `mode: ISTIO_MUTUAL`
# in each DestRule to tell Istio that even though we have a custom destination config, we still want mTLS.
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: {{ .serviceName }}-custom-spire-destrule
spec:
  host: {{ .serviceName }}
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
      subjectAltNames:
      - spiffe://example.org/ns/{{ $.Release.Namespace }}/sa/{{ .serviceName }}/wl/foo

Once you do this, SPIFFE IDs can be constructed with whatever level of granularity you desire, and workload certs can be distinguishable by consumers at the level of attestation that is actually performed by the SDS, rather than the level of attestation that Istio's default SDS performs.

There has been resistance to changing the default SPIFFE ID format due to back compat with existing customer rules that also hardcode SPIFFE IDs in the format that the default Istio SDS emits, and that's reasonable - but given that we support pluggable SPIFFE-compliant SDS implementations there is no good reason why Istio itself should forbid or otherwise prevent customers from using an alternate SDS from using more granular SPIFFE IDs than the default.

Especially since this works fine today with a simple DestinationRule tweak, indicating that the problem is a simple set of currently-unconfigurable defaults, and not a systemic obstacle.

Frankly, outside of maybe requiring that a SPIFFE ID have at a minimum several expected parsable fields in it so Istio itself can extract the information it needs from SPIFFE IDs (/ns/<namespace> and /sa/<serviceaccount>/), it isn't really Istio's business what the SPIFFE ID format is - the SPIFFE ID format is and should be owned by the SPIRE-compliant SDS instance, and we support more than one SPIRE-compliant SDS instance. We just make bad assumptions elsewhere in the code that force those compliant instances to hew exclusively to the SPIFFE ID format our default SDS emits, which is an unnecessary restriction.

Affected product area (please put an X in all that apply)

[x] Ambient
[x] Docs
[x] Installation
[ ] Networking
[ ] Performance and Scalability
[ ] Extensions and Telemetry
[x] Security
[ ] Test and Release
[x] User Experience
[ ] Developer Infrastructure

Affected features (please put an X in all that apply)

[ ] Multi Cluster
[ ] Virtual Machine
[ ] Multi Control Plane

Additional context

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions