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

Could a SVID be verified by a client process that is not itself a workload? #132

Open
paulhowardarm opened this issue Jul 30, 2020 · 8 comments

Comments

@paulhowardarm
Copy link

Summary

Would it be possible to allow a client process to call the Workload API solely for the purposes of verifying a signed SVID and obtaining the SPIFFE ID string?

Detail

It's currently only possible for a client to call the Workload API if that client is itself a registered workload. However, it might be a valid use case for a client process to be able to call the API solely for the purpose of verifying a SVID and extracting the SPIFFE ID string.

The use case is as follows. Suppose we have a storage service that partitions stored assets according to a name-spacing scheme. And suppose that we have a SPIFFE-based system where we want to use the SPIFFE IDs as the name-spacing token within that storage service. The service would allow, say, a calling process with an id of spiffe://my.system/application1 to store assets in a separate area from spiffe://my.system/application2. This could be achieved by having the client processes call the service using a signed SVID for authentication. They obtain that SVID using the Workload API in the normal way. But the storage service then needs to be able to verify the SVID and extract the SPIFFE ID in order to use it for name-spacing. If the storage itself is not a SPIFFE workload, then it currently can't do that.

If the storage service could call just the verify operation on the Workload API, and get the SPIFFE ID back, then this use case could be enabled.

@spikecurtis
Copy link
Collaborator

I'd like to understand the use case in some more detail.

How do the clients validate the authenticity of the storage service?

The reason I ask is that we've generally considered SPIFFE to be a framework that encourages and enables mutual authentication (client authenticates server, server authenticates client). So, is the plan for this use case for clients not to authenticate the service, or for them to authenticate in some non-SPIFFE enabled way?

Is there some particular reason the storage service cannot or should not be a SPIFFE workload?

There isn't any requirement that a workload that obtains an SVID actually assert that SVID anywhere. So, is there some reason you don't want the storage service to be issued a SPIFFE ID and SVID that it ignores?

@paulhowardarm
Copy link
Author

Thanks for responding, Spike.

The storage service was a somewhat hypothetical case. I work on the Parsec project (recently adopted in CNCF Sandbox). Parsec provides a uniform software abstraction over secure facilities of a host platform (such as crypto and key storage). One of Parsec's roles is to act as a brokering service to multiple client applications, allowing them to share access to secure key stores that might ultimately be underwritten by hardware protection such as a TPM or HSM.

So Parsec is the hypothetical storage service I mentioned, in the use case I am aiming for. It is a storage service in the sense that it stores assets such as keys.

For Parsec to function in a world of multiple distinct clients, it uses a name-spacing system to keep the assets of each client separate. There is no single specification of what the name-spaces are: that's one of many ways in which Parsec tries to be agnostic of its environment. It could, for instance, be something as simple as the UID of the calling process. However, we have identified that it might be useful for SPIFFE workload IDs to be one supported means of doing it. In this model, Parsec would have an authenticator module sitting on its front-end, which would accept SVIDs alongside the API calls coming into the Parsec service from clients. These SVIDs need to be verified and converted into SPIFFE IDs, which are then used for name-spacing.

With that piece of background, I can turn to your questions.

The Parsec service represents the secure facilities or root-of-trust of a single host device. In that sense, Parsec is "tied" to its host rather than to a trust domain of workloads. The means of trusting Parsec would be host-specific, and Parsec-specific. The idea here is to use SPIFFE IDs as one of many possible options for keeping clients segregated. So isolating that functionality into a single authenticator module, rather than require the whole Parsec service to be a participant in the trust domain, is a cleaner model from my perspective.

As for whether the Parsec service could have a SPIFFE ID, I'm not sure. I suppose it depends. But I think my concern would partly be one of circular dependencies, because we are also talking to the SPIRE project about possibly integrating Parsec for platform root-of-trust abstraction as well. Requiring Parsec to be a workload might result in a circular bootstrapping issue.

Leaving the specific concerns of Parsec aside, I feel that it might be a generally valuable and reasonable use case to be able to verify/extract SPIFFE IDs without necessarily being an active participant in the trust domain. Verification feels conceptually like a public activity that any audience process could be allowed to do.

@paulhowardarm
Copy link
Author

Just to clarify one important point: Parsec is explicitly a host-local service. It is a software agent that represents the secure back-end of a single host device. There is an IPC mechanism between the Parsec service and its client applications, but all comms are device-local. Clients do not communicate with Parsec over a network.

@spikecurtis
Copy link
Collaborator

Thanks for that background, it helps a lot. A couple comments on a number of issues:

I don't think there is anything in the SPIFFE Workload API spec that explicitly requires the caller to have an SVID issued in order to verify SVIDs. Is there any specific text you're worried about? It sounds like you are considering JWT SVIDs (since you referred to them as tokens). The RPC to validate a JWT is independent of the one that issues a JWT, so in theory you could validate without ever being issued a SPIFFE ID. It may be that SPIRE doesn't allow unregistered workloads to do this, but that's a SPIRE rather than a spec thing.

The second thing is that re: concern about bootstrapping between Parsec and SPIRE, I don't see how Parsec could receive a request with a SPIRE token until after SPIRE is bootstrapped. Also, SPIRE would have to be bootstrapped before it could answer any validation requests over the Workload API.

@azdagron
Copy link
Member

The Workload API spec does have some language around this:

https://github.com/spiffe/spiffe/blob/master/standards/SPIFFE_Workload_Endpoint.md#6-error-codes

Finally, in the event that a SPIFFE Workload Endpoint service does not have an identity defined for a given caller/client, the service SHOULD respond with gRPC code "PermissionDenied".

@azdagron
Copy link
Member

The above text was surely written when there was only a single method (i.e. FetchX509SVID). FetchX509SVID has text that prohibits a response that does not contain an SVID.

The only mandatory field in the X509SVIDResponse message is the svids field. If the client is not entitled to an SVID, then the server SHOULD respond with the "PermissionDenied" gRPC status code

This would preclude somebody from hitting FetchX509SVID to obtain X.509 authorities it could use to validate X509-SVIDs without being a workload itself.

I don't think we've completed the text for the JWT related RPCs so it isn't too late to add clarifying language if we want to open up FetchJWTBundles and ValidateJWTSVID to allow unauthenticated clients.

@spikecurtis
Copy link
Collaborator

Thanks @azdagron, I missed those sentences in my quick skim.

@paulhowardarm
Copy link
Author

On the point of the bootstrapping issue above, I would not expect SPIRE itself to be authenticating to Parsec using a SPIFFE ID. Only general client applications would do this once the system is up and running. There would be some kind of root mechanism by which SPIRE would talk to Parsec. Details of this are still somewhat in flux, but would likely involve something like a separate socket endpoint that uses a different auth mechanism, possibly based on OS constructs such as UID.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants