Skip to content

Identity TLS Cert Auth: optionally validate the client certificate chain against the configured CA as a trust anchor #7020

Description

@sinnwise

What I'm trying to do

I'd like to authenticate workloads to Infisical using their SPIRE X.509-SVIDs through TLS Certificate Auth, with no static credentials and no JWT.

A SPIRE workload already holds an X.509 identity whose chain looks like this:

leaf (SPIFFE SAN)  ->  SPIRE signing intermediate  ->  SPIRE root CA

That seems like a perfect fit for TLS Cert Auth — the workload presents its leaf, Infisical validates it against a CA. The problem is which CA you're allowed to configure.

Where it breaks

TLS Cert Auth today is single-hop: the leaf must be signed directly by the configured caCertificate. In SPIRE, the cert that directly signs the leaf is the signing intermediate, and that intermediate rotates often — in our deployment roughly daily (SPIRE stages a "prepared" intermediate ahead of time and swaps it). The root, by contrast, is stable for years.

So to keep auth working, I'd have to configure the rotating intermediate as the caCertificate and run a controller that watches for each rotation and PATCHes the identity's CA on every swap. One per trust domain. We run ~31 clusters, each its own SPIRE trust domain, so that's 31 rotation controllers — each one a moving part that, if it falls behind, breaks authentication for that cluster.

Cross-cluster makes it worse: SPIRE federation only shares roots, never intermediates. So a central Infisical can't even obtain a peer cluster's current intermediate to sync it. The intermediate is reachable only from inside the cluster that owns it.

What would fix it

The thing I can reliably get my hands on — locally and through the federated trust bundle — is the stable root. I just can't use it today, because single-hop verification won't accept a root that didn't directly sign the leaf.

The fix is the same pattern every other SPIFFE consumer (Envoy, Vault, ...) already uses: treat the configured CA as a trust anchor and let the verifier walk the chain the client presents up to it. Pin the root once, done — no sync controller, no static credentials, and it works the same way across clusters from the federated root.

Proposal

Add an opt-in, per-identity boolean (something like verifyClientCertificateChain, default false):

  • false (today's behavior, unchanged): the leaf must be signed directly by the configured CA.
  • true: the configured CA is a trust anchor. The client presents leaf + intermediate(s) (exactly what a SPIRE X.509-SVID already contains), and Infisical validates a path from the leaf up to the anchor — checking the issuer relationship and signature at each hop, that issuers are CAs, and that every certificate on the path is within its validity window.

The configured CA stays the only trusted certificate. A presented intermediate is just an untrusted input: if it doesn't chain to the anchor, it's rejected. And everything #6913 added still holds — the leaf must be an end-entity certificate (a CA cert presented as the client cert is still refused), and SAN/CN checks (#6957) still apply to the leaf.

References

Happy to send a PR — I have an implementation with tests ready to go.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    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