-
Notifications
You must be signed in to change notification settings - Fork 472
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
Consider carry custom extension fields in svid #4189
Comments
Thanks for opening and issue! I have a few questions to try to understand your request in some more detail. As you mention, JWT and x509 support custom extension fields. The SPIFFE specs for these SVID types are written such that they allow custom extensions to be included. E.g. from the JWT-SVID spec:
So, is your request that SPIFFE specs allow custom claims in SVIDs? If so, I believe that is the current state of affairs. You mention implementation in SPIRE: is the request that SPIRE provide an API to allow you to inject custom claims into SVIDs it mints? If so, I think this request would be better directed to https://github.com/spiffe/spire. The spec working group standardizes the Workload-API that SPIRE implements, but does not specify the administrative or operator APIs that SPIRE uses. Or, is your request not covered by either of the above situations and I'm just not understanding what you are asking. If so, would you mind restating your proposal with some more detail? |
Thank you for your response. |
I will point out that SPIRE supports a CredentialComposer plugin that operators can implement to add arbitrary extensions to both X.509 and JWT SVIDs. This was added somewhat recently. |
It looks very cool. And do you have any design specification and using guideline for developers to dive deep into? |
@azdagron i quickly look through the source code about the CredentialComposer, i agree that developers could leverage this plugin to add extensions to X.509 and JWT SVIDs. However, if the extension values are binded to workload itself (eg. trace id of the task which is running on certain workload), how could we deal with this problem? |
That's right. Although maybe the spec could be more explicit on this point, the SVID spec is meant to be interpreted as restricting a few key fields/extensions of an otherwise valid x509 certificate. Any fields/extensions not mentioned in the SPIFFE specs are unrestricted. |
Hey @chenxi-neo, at this point we're diving into the weeds with SPIRE. Do you mind if I transfer this issue over to that repo? |
i think it's a good idea to transfer this discussion to spire repo. i looks good to me |
Hi @chenxi-neo, unfortunately there is no current way to feed workload properties into the Credential Composer. There are a few reasons for this, one of which is that at least the X509-SVIDs are signed well in advance of workload attestation and cached by the agent (for availability purposes). Is the information you want to add to the SVIDs present in the registration entry selectors? |
@azdagron i agreed that with the current architecture of the spire, it’s hard for operators to add workload-defined extension/properties into SVID. i think the entry selectors should only carry information about the identity attestation. But in our scenario, general properties, such as task trace id, which are not directly relative to the identity may also need to be carried by the SVIDs. The current solution in our scenario is to let spire sign a downstream CA for our identity issuer service, and the identity issuer will sign SVIDs with custom properties the workload wants. However, this solution is not spire native and has some security compromise. |
Hi, I like to support this request as I'm looking for a similar solution. I.e., the goal is to add custom attributes to an X509 SVID. From my understanding this could be achieved by SPIRE providing the following capabilities: (1) allow to manage custom attributes as part of a registration entry From my point of view the fields that are currently supported by SPIRE are not suitable for this use case. E.g., 'selectors' are used to derive which agent can serve which workload, 'hints' are sent to the agent, 'DNSNames' are close but have a defined semantics (not sure whether DNSNames could technically be used for this today). |
In order for SPIRE Server to sign SVIDs with workoad-specified properties included in it, SPIRE Server must have a strong understanding of the meaning of the workload-specified properties, and/or some way to validate it. The only workload-specified property currently allowed into an SVID is the
I agree that the current fields are not suitable for this. There's a great deal of hesitancy to allow the storage of arbitrary data on an entry ... however, a credential composer plugin could be loaded with data, or call out to fetch this data ... and this data can be referenced via data in the entry (e.g. entry ID, SPIFFE ID, etc). Would that be a suitable solution? |
Indeed, we can have the credential composer plugin to call out and fetch data (i.e. additional attributes to be included in the certificate) using e.g. the spiffe Id (or something similar) as a reference. Yet, it feels like a workaround to access an external service (e.g. the one that is used as management plane to create entries in the Spire server) from the Spire server's credential composer plugin to retrieve data that Spire couid easily handle. Furthermore, it comes with additional complexity, e.g., management of credentials, support of spiffe ID (or entry Id) as key in the external service as Spire does not allow to handle the external service's native identifier/key, and potentially caching. Still this can be done. On the other hand, one would not have to do this, if one encodes all the information into the SpiffeId itself. Why does Spire make such a difference whether attributes are included in the SpiffeId (e.g. spiffe://example.com/attrib1/attrib2/attrib3) or in another place in the certificate. Some background on the design that I'm currently brainstorming: The SpiffeId is mainly an identifier, i.e., it is granted to be unique per trust domain, and equality of SpiffeId's is checked using a simple string comparison. Example SpiffeId: e.g. spiffe://example.com/0bfc399e-74c9-42ce-978f-13fdca86582d. This identifier must not change even if over time new attributes are to be introduced. The attributes of the entity represented by this identifier (like tenant, namespace, cost center, ... - people and use cases ask for different thing that will change over time) should be encoded in a data structure that can be easily extended and handle key-value-pairs - a Json object looks like a good choice e.g. {"tenant":"abc", "costcenter":"123", ...}. In the certificate, this Json object could be included as part of the "subject directory attributes" (see RFC 5280) - e.g. by introducing a new Subject Directory Attribute JSON object - likely this requires to register a new OID. For interop reasons, one may consider to use base64/base64url encoded representation of the Json object, which can be represented as IA5String. The inclusion in a JWT could be either top-level or a JSON object under a dedicated key like "attributes" (I currently focusing on the x509 use case). A receiver needs to interpret the information provided in subject directory attributes of a certificate (or attributes claim of a JWT) based on the documented contact defined by the owner of the trust domain. Alternatively, the receiver might just look at the subject DN or the SpiffeId in the SAN to get the entity's identifier. |
I think this statement could also be reversed 😅
It's less about where in the SVID that information goes, and more about whether it should be in the SVID at all. SPIFFE has written about this extensively - section 4.1.1 is probably the most important IMO. The other three sections are also important in federated environments. IMO, the storage, maintenance, and distribution of that kind of information isn't well solved generally. OPA has a concept called a bundle which is getting closer, but I think there's a lot of tooling needed to manage them. NGAC seems to have a similar idea as well, distributing a graph with all the data needed to make an authorization decision. In the end, the needs around this "authorization metadata" is pretty different than the needs around identity document data, and it's usually best to handle it separately. That said, people can (and have) encoded this kind of information into SPIFFE IDs 😅 We've had several conversations about this issue in public contributor and maintainer calls, and as I mentioned before the reception to an opaque field on the entry has so far been poor. I think we'll either need to have a deeper understanding (and stronger typing) around what we're proposing to put on the entry, or we'll have to find some other way. FWIW, I think that SPIRE exposes a host service allowing plugins to get X509-SVIDs and bundles so they can call out to other services in circumstances like this |
@evan2645 : I would fully agree that "the storage, maintenance, and distribution of that kind of information isn't well solved generally". If there would be clear best practices, I would be happy to follow. Yet, as there are no clear best practices, I'm looking for an approach that allows to gain further experience how to include selected attributes in a certificate based on the following constraints:
Due to (1) and (2) I like to keep those attributes outside the SPIFFE ID. Due to (3) I'm looking for a way to include the information in the certificate (would be similar for a JWT) instead of offering an API that allows to retrieve this information given a SPIFFE ID. Currently, the most common approach using SPIRE seems to be to encode the selected attributes in the SPIFFE ID (which would fulfill the constraints (1) and (3), but not (2)) - see also https://youtu.be/DXE6CDJjDV4?t=1093. As mentioned above with the help of the credential composer plugin, it should be possible to fetch information from an external service and include them in the certificate - while support for additional attributes in SPIRE's persistence would ease setup for us. If you have any further recommendations or could share some experience from SPIRE deployments on the topic, maybe also on 'where to include' these kind attributes in an X.509 certificate outside the SPIFFE ID, I would be very interested. |
Thanks for the thoughtful response @sebastianGit, point 3 is especially useful to know.
I'm happy to make a personal recommendation if it's valuable to you 😅 I have a few more questions below that will help me narrow it down, if you don't mind.
What's your level of comfort with this information getting out? For example, observable on the wire, or handed to a third party e.g. during federation? Does it need to be held confidentially in any way?
Out of curiosity, if a performant local API was available to retrieve this information, would it solve your problem? It seems like you might be saying "Due to 3 I can afford to put it in the SVID somewhere" but not necessarily that it has to be there? Finally, what degree of control do you have over the software doing the SVID validation? |
@evan2645 I'm happy to follow up on this.
The ultimate requirement behind this topic is that receivers of the client certificate have a need to retrieve 'selected' attributes about the subject entity represented by the client certificate's subject (here: let's restricted 'selected' attributes to 'attributes that do not change over the lifetime of a workload' and exclude any dynamic attributes). This can be achieved using multiple ways, especially considering push vs. pull:
In the pull/API case, the API should be simple, e.g. input: certificate/subject DN/spiffeID, output: some attributes on subject; additionally authentication/authorization should not require any/too much active management effort (e.g., callers of the API are authenticated via a client certificates, and authorized to call the API, if the client certificate is from a trusted issuer). The benefit of including the information in the certificate comes from the fact that this does not require additional efforts (esp. calls) by the presenter nor by the receiver of the certificate. Also, for the certificate issuing service the effort is limited, esp. if the relevant attributes are available to this service anyway. The drawback is that there might be information on the wire, which the receiver is not interested in. Thus, it needs to be carefully designed what to include given the use cases. Open: where to include the attributes in the certificate. The benefit of offering an API is that the information can be requested on demand and that there can be a custom authorization model. Yet, requesting information on demand comes with additional efforts (1) for the receiver of the certificate (calls, caching, need for a credential for authentication, ...), (2) for the service offering the API (performant API, simple or complex authorization model, ...). While both is possible, I'm currently in favour of aiming to include selected attributes into the certificates.
Well, as this is a trade off, it needs to be considered when deciding which information to put into the certificates given the use cases. As the subject uses the client certificate in a request to someone trusting the issuer of the certificate there is already some trust relationship between the parties and a joint use case. Assuming there is an API with a simple authorization model (see above), there might not be too much of a difference.
That's a good one. Answer: None. Yet, I would argue that a receiver of a certificate that is able to call an API and make the retrieved information available to the business logic that needs the information, is also capable of parsing the information from a certificate and make it available. Yet, this brings me back to the question where to include the information in a certificate such that (1) it provides interoperability and (2) it is easily/commonly supported by OSS to retrieve the information in a developer-friendly way, and (3) it supports static subject identifiers as well as the flexibility to adjust the provided attributes over time (being able to explicitly express key-value-pairs). What about considering a SPIFFE-standardized object identifier (OID), that allows to include a JSON object in the Subject Directory Attributes in an X.509 certificate. |
@evan2645 : Here a sample certificate containing a base64-encoded Json Object in the 'description' attribute (see RFC 4519) included in the Subject Directory Attributes. Note: Ideally, it would be possible to find/define a better attribute than 'description' - which as part of it's definition says that the attribute is a base64-encoded representation of 'selected attributes' of the subject.
Sample Go code to generate the certificate see: https://go.dev/play/p/BQfqbmh8m4T Sample Opa/Rego policy trying to read the Subject Directory Attribute see: https://play.openpolicyagent.org/p/u8hkmNN9ja |
My feeling is that it will be hard to achieve all of these things at the same time. A custom extension is probably the safest thing to do.
I think if it's going to be defined in SPIFFE, it needs to have some concrete meaning about it, with guidance on how to interpret it etc. It's hard for me to see value in standardizing a spot where you can stick some opaque JSON, and it's also hard for me to see a scalable answer in the other direction (actually define the attributes and their meanings) This is one of the reasons I suggest a custom extension - it's organization specific, the only folks that should be looking into it is you all, who understand the meaning of the data in it and how to consume it safely. In JWT land, this is often accomplished by putting your custom data under a collision-resistant key ... so in some ways, this suggestion is the equivalent for X.509. |
Yes, my understanding is also that including additional attributes about the subject in a certificate using a ‘custom extension’ is conceptually analogous to adding the attributes as part of a ‘custom claim’ in a JWT. Yet, on the practical side things a more complex in the context of X.509 certificates compared to JSON.
Depending on whether the need for being able to include additional attributes about the subject as part of a certificate is of larger interest to the SPIFFE/SPIRE community, the agreement on a preferred place where to put those attributes within an X.509 certificate and in which format can significantly ease the introduction of the required capabilities for being able to ‘access/read’ the attribute information into Open Source Software. Would you agree in general? Is there a larger interest in this topic? |
Yes, I agree in general that there is interest here and that the general problem of how this data is generated, moves around, and gets consumed, is not well solved. I just don't think that SPIFFE is the right place to solve it (though I do have one idea of a better place we could bring it). IMO, SPIFFE's job is to provide a federated workload identity layer that supports multiple credential types. The reason it supports multiple credentials is that not all are created equal, and some are better at certain things than others. Lack of flexibility around parsing custom X.509 extensions is a downside of the credential format, and orthogonal to SPIFFE. I don't think it's SPIFFE's job to define a more flexible way to pack arbitrary information into an X.509 cert. I do think this is important work that needs to be solved, and we need to figure out where. I've been part of some recent conversations in IETF about this specific topic and more. It is still early there, but it would be great to have you weigh in. You can join the mailing group here. |
hey @sebastianGit , I hope you're doing well and that my previous comment made sense. I've raised this topic with the IETF WIMSE group and posted a mail about it. I feel the problem fits pretty squarely within the proposed WIMSE charter, and I hope that you can participate and help carry the conversation there along with me. Happy to jump on a Zoom or chat on slack DM about it further if that's helpful, just let me know. I'll go ahead and close this issue out for now, pending further movement in IETF WIMSE. I really appreciate all that you've contributed on the thread thus far, it is incredibly helpful in finding a path forward ❤️ |
We hope to be able to carry custom extension fields in jwt & X509 svids to meet business needs. Currently, we use spiffe/spire as the basic authentication infrastructure for micro-service. Some of our internal upstream businesses hope to carry some custom extension fields through jwt or x509, such as: trace_id, taskname, etc. This information is parsed in the downstream business for authentication or other purpose . Both JWT and X509 standards support custom extension fields. JWT can be based on custom claims, and X509 can be implemented through v3 extension. We would like to know how the community thinks about this proposal, and whether this specification can be written into the spiffe standard and implemented in spire. Currently, we are exploring this proposal internally, and if the community is interested, we can also work with the community to build this capability. If the community does not accept the proposal, does the community have a better idea of the above problems?
The text was updated successfully, but these errors were encountered: