Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Suggestion: SPIFFE authentication plugin #25

Open
bnevis-i opened this issue Dec 15, 2023 · 2 comments
Open

Feature Suggestion: SPIFFE authentication plugin #25

bnevis-i opened this issue Dec 15, 2023 · 2 comments
Labels

Comments

@bnevis-i
Copy link

bnevis-i commented Dec 15, 2023

Summary

Support a SPIFFE authentication plugin that would allow a user to obtain an authentication token via SPIFFE mTLS.

Problem Statement

The problem that any user of OpenBao must immediately confront is "how do I get an authentication token?" Some ways that this can be done include include: userpass (username/password), approle (similar to userpass, but supports two "passwords" in order to enable credential rotation), raw tokens (someone hands you a bare token with some kind of policy attached to it), and others. The problem with most of these is that the token, password, secret, etc. must be pre-provisioned and made available somewhere in a protected location.

SPIFFE aims to solve this "bottom turtle" problem by using workload attestation to provide an on-demand credential to a workload. The workload does this by connecting to an agent over a Unix domain socket, and the agent looks up the workload in the process table, docker runtime, kubernetes runtime, systemd runtime, etc. to ascertain various properties about the workload. These properties are looked up in a table, and if the workload is "known" (for example, by the sha256 hash of its executable, or name of the Kubernetes pod), an identity (SVID) is issued to the workload, usually in the form of a private key and certificate, though JWT-SVID is also an available format. The effect of this is that the workload no longer needs access-protected configuration files, connections with a secrets manager, or the like to get a credential that will authenticate the workload on the network.

SPIFFE authentication is not like normal mTLS. The certificate lifetimes tend to be very short, and authentication is based on attributes of the certificate, such as the SPIFFE ID and trust domain. The normal rules such as the DNS name needing to match CN or subjectAltName no longer apply. The go-spiffe library, for example, replaces the TLS logic entirely with its own implementation.

Today's solution is documented in https://spiffe.io/docs/latest/keyless/vault/readme/ which relies on a JWT-based SVID and configures the OIDC authentication plugin to establish trust. It is overly complex in that it requires creating extra runtime components just to get the plumbing set up, where the ideal state is to just connect to OpenBao and get a token.

User-facing description

A simpler solution would be to enable OpenBao to attest with SPIFFE and obtain a server-side X.509 SVID to present on a TLS serving port. A client would also attest with SPIFFE and connect to the OpenBao SPIFFE authentication endpoint. Based on the client's SVID, an appropriate authentication token would be issued.

Note that there is some overlap wtih #17, which discusses, among other concerns, how to auto-provision a TLS certificate. (There is a capability to set the subjectAltName in a X.509 SVID to make it more like a normal server certificate.)

@bnevis-i
Copy link
Author

Disclaimer: no current plans to use such a feature, but I have had to work around this feature not being available in the past and I think it would help OpenBao play nicer in the open source security ecosystem.

@cipherboy
Copy link
Member

cipherboy commented Dec 19, 2023

SPIFFE authentication is not like normal mTLS. The certificate lifetimes tend to be very short, and authentication is based on attributes of the certificate, such as the SPIFFE ID and trust domain. The normal rules such as the DNS name needing to match CN or subjectAltName no longer apply. The go-spiffe library, for example, replaces the TLS logic entirely with its own implementation.

I think this doesn't preclude mTLS listener if you drop in a Config.VerifyPeerCertificate and Config.VerifyConnection helper, as its "just" mTLS with other rules. IOW, if you fork the cert auth backend, you can likely modify it to do what you want, without a parallel TLS stack.

So perhaps we can distill the go-spiffe library (or better, contribute upstream) to a handler implementation of the above, and modify cert auth to have better semantics for issuance/validation (likely removing revocation checking?) to allow SPIFFE.. It kinda looks doable, though I'd probably want to run it by the library authors before proposing it as a PR.

This is looking a lot more tractable than replacing the entire TLS stack for everything, IMO. If someone wants to do the work, happy to offer suggestions & guidance.

cipherboy pushed a commit to cipherboy/openbao that referenced this issue Jan 21, 2024
Use go 1.20.2, and update x/net to v0.8.0:

golang.org/x/net v0.5.0 => v0.8.0
golang.org/x/sys v0.4.0 => v0.6.0
golang.org/x/term v0.4.0 => v0.6.0
golang.org/x/text v0.6.0 => v0.8.0

Update k8s versions and add 1.26.2. Use known GHA SHAs in the test
workflow, update helm/kind-action's version and remove
azure/setup-kubectl in favor of the kubectl_version option on
helm/kind-action.

Removes the extra caching steps in favor of setup-go@v3's built-in
caching support.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants