Closed gcapizzi closed 2 years ago
We are now happy with this spike. We moved the client certificate CA and validity date checking to the shim https server, where it should be, and now we don't do any custom security ourselves.
How to run this spike:
cd certs
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -subj '/CN=localhost' -addext "subjectAltName=DNS:localhost,IP:127.0.0.1" -days 3650
certs/ca.pem
(extract from the kubeconfig and base64 -d
)APICONFIG=api/config/base/apiconfig go run ./api/main.go
make build
in the cli sourceexport SSL_CERT_FILE=~/workspace/cf-k8s-controllers/certs/cert.pem
cf api https://localhost:9000
cf login
Background
Currently our API shim accepts client certificates in the
Authorization
header, using theClientCert
scheme. It then uses the cert and key stored in the header to build a user-scoped client that it uses to talk to the Kubernetes API.We believe this approach is as secure as tokens: in both cases we're sending a secret over the wire which could allow an attacker to impersonate the user. But while this is always true for tokens, this is not the case for certificates when used in the intended way: when establishing a mutual TLS connection, the user's private key never leaves their machine. In other words, mTLS is intrinsically more secure than tokens, and our treatment downgrades them to the same security level as tokens.
We'd like to explore a different way of accepting client certificates, which doesn't require the user's private key to ever be sent to the API. Here's what we could do:
http.Request.TLS.PeerCertificates
).Let's try implementing this and assess which changes would be needed both on the shim and on the CLI.
Acceptance Criteria
A git branch containing a working proof-of-concept of what described above.
Dev Notes
Some work has already been done on this, see
eirini-forks/cli@spikes/mTLS
andcloudfoundry/cf-k8s-controllers@spikes/mTLS
.