SSL and x509


I’m trying to setup x509 authentication in addition to OAuth authentication for my Spinnaker instance. I need this to allow script access to the instance.

While reading the official guide and the one from Armory I see that settings for x509 authentication are interleaved with SSL settings? Why? To me they sound like completely independent things.

In our setup we run Spinnaker on GKE and have SSL terminated at Kubernetes ingresses. So that Gate and Deck pods expose plain http endpoints. When I enable x509 as described in the guides above (which implies enabling SSL) I see that Gate exposes https endpoints:

INFO 1 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8084 (https) 8085 (https)

Also in the Deck UI I see the following error:

Bad Request
This combination of host and port requires TLS.

Does it mean that if we want to enable x509 authentication for Gate we need to revise our complete SSL setup?


I’ve only worked with X509 in a limited capacity but from what I have done, here’s what I know:

When authenticating with an X509 client certificate you’re simply validating that you can establish a connection with the server. If you can, you’re authenticated. If you can’t, you’re not. To do this, the server needs a way to verify the client certificate, which is done by setting up SSL on Gate. I don’t think you’ll need to revise your SSL setup but you’ll probably need to make a couple of tweaks make sure that things pass through properly. For example, you’ll need to handle the case where a user is connecting with a client cert and pass the traffic directly to Gate. You’ll also need to make sure that the Ingress controller forwards things like protocol and host headers so that redirects are properly built.


@ethanfrogers is right - X509 auth is interleaved with SSL because the authentication of the user is happening at a lower level of the OSI stack than the other authentication modes.

Specifically, this authentication is happening through the public key exchange. Typically, only the server needs to authenticate to the user’s browser (to let the user know they’re talking to the right entity - to ensure you’re really talking to your bank, for instance, and not something else impersonating your bank).

With X509, not only is the server authenticating to the user, but the user authenticating to the server - known as mutual authentication. This is done using the same mechanism - basically “is the certificate presented from X to Y trusted by Y?” That question is answered through the use of certificate authorities.

The end result is still an encrypted channel, much like it was before. You may be asking “Can I setup X509 without SSL?” and that answer is no - the Tomcat server implementation does not allow this (AFAIK).


@ethanfrogers @ttomsu thank you for the explanation. Now I know WHY we need to enable SSL in Gate. But the next question is HOW to do it properly in my situation when we have Kubernetes ingress controller where SSL is terminated.
Alternatively I’m looking for another authentication method that I could use for script access (in CI pipelines for instance). Something as simple as basic auth would work but we have Fiat authorization enabled so we need some way to associate group info with it.


Also I don’t fully understand why we need to enable an additional port

  apiPort: 8085

The configuration adds an additional port for x509 certificates. This is so you can terminate HTTPS to end-users of the UI on the ELB and continue using API on a different port with x509 client certificates.

Thus Gate will have 2 exposed ports but I didn’t find a way to setup SSL only on one of them. Also by Spinnaker service doesn’t expose the new port:

spin-gate                    ClusterIP     <none>        8084/TCP,8008/TCP   2h

So I’m wondering how scripts are supposed to reach it


@wheleph I’ve personally used Foxpass for LDAP which will allow you to use Basic auth with scripts.

Also, the apiPort option enables you to use x509 for authentication on one port and another auth mechanism on the default port (8084).


Regarding apiPort there are some hops to jump through:


Docs from Armory mention that one needs to import both CA and client certificates in a keystore file. I understand that the file is used by Gate to authenticate clients.

But I noticed that if I generate a new client private key and create a certificate based on it using the same CA, then that certificate is also accepted by Gate (although that certificate is not in the keystore).

This sounds natural because web browsers do not contain certificates of all servers on the internet, they just have CAs. So the same should apply when a client authenticates to the server. And from this standpoint the inclusion of client certificate in Gate’s keystore is redundant. Is it true or am I missing something?


Hi @wheleph,

I’ve noticed the same with our setup - I only had to add the private self-signed CA to keystore (actually I did split between keystore and truststore here - although the docs in are saying you could use the same file).

I had a feeling also that “oh, it works without” but it must be the CA-thingy… Which kind of makes it handy. I’m issuing now certs to our devs which have a shorted expiry time (in the future I’d give this job to e.g. Hashicorp Vault)…

@wheleph are you also using Fiat? I’m having troubles with roer + pipeline templates - getting an interesting error when I try to publish a pipeline-template :slight_smile: Saving pipelines works like charm but…


@iiro pipeline templates are handy but we decided not to use them because their security model is not very complete: Security model for declarative pipelines (pipeline templates)


@ethanfrogers @ttomsu can you confirm that the behavior described above is correct? Namely that it’s only required to add CA cert into keystore/truststore of server (Gate) and adding of client certificates is not required?