-
Notifications
You must be signed in to change notification settings - Fork 39.7k
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
Using annotations for new API features creates the potential for security lapses #30819
Comments
@kubernetes/sig-api-machinery @bgrant0607 |
On Wed, Aug 17, 2016 at 2:26 PM, Clayton Coleman notifications@github.com
|
Alternative solution: Reserve |
We probably want something that explicitly disables certain API features at admission and on egress (Tim raised that on the service external name issue) based on the state of flags. Annotations are marginally easier to deal with in bulk via admission / generic code. A weakness - a typo in a client library would bypass the whitelist filter (controller reads "alpha.kubernetes.ios/*" rather than ".io"). Smaller gap and would likely be caught in review, but isn't fail safe. |
Re: admission - that can also potentially address #4, but we don't support nested admission chains today and would also be vulnerable to new code coming in that the admission chain doesn't check. |
Let's prefix alpha field names with the actual letter alpha/ |
I would be OK with this approach. I feel like we considered it in the past and rejected it, but I have lost state, so... I do feel like ad-hoc is just not working. |
I've lost state too - I know the "preserve data after the new field goes On Wed, Aug 17, 2016 at 7:29 PM, Tim Hockin notifications@github.com
|
I don't remember all the states neither since we quickly rejected the idea. One of the reasons is that we worried too many duplicate fields in one API object. But we are doing this today if the feature was introduced as non-alpha initially, and need to change later; the only difference is introducing the field with a new name without prefix. I think that is even less manageable. Another reason is back then, we thought we can skip both conversion and validation logic at master side and simply pass it through to other components, like Kubelet to take care the rest. For example, kubernetes.io/ingress-bandwidth, the validation is done at Kubelet. But in reality, we do both conversion and validation for those alpha feature today. I believe there must be some other deep reasons, but above are all I can remember. |
I propose we leave this until post code-freeze. We're not changing tracks On Wed, Aug 17, 2016 at 6:07 PM, Dawn Chen notifications@github.com wrote:
|
Agreed with @thockin at #30819 (comment) I will continue processing AppArmor changes as is. |
Yes this is marked as a 1.5 thing now. |
More specific example of OP's item 4: If you wanted to give kubelet only the privileges it needs, you might want to give it permission to update Status, but only to read Spec. Init-container status is stored in annotations. So you cannot do that. |
I thought you could write to annotations by posting to the status endpoint? On Thu, Aug 18, 2016 at 9:12 AM, Eric Tune notifications@github.com wrote:
|
@smarterclayton @thockin @lavalamp @erictune @dchen1107 @timstclair @davidopp Several of the reasons why we started to use annotations in this way are mentioned in this issue, and a number of them have both advantages and disadvantages:
Multiple fields representing the same information are very tricky to deal with regardless whether we use fields or annotations. I'll throw out another idea, which is that we could adopt semantic versioning for API versions, and rev a minor API version (e.g., v1.3) when adding a field. That would enable us to avoid the multiple-field problem. Anyway, I'm ok with using fields rather than annotations. In practice, the level of forward compatibility we ensure is probably determined by the number of users of a feature more than mechanism (annotation vs field) or even policy (alpha vs GA). |
perhaps we should elect a small (2-3) number of these to trial in the 1.5 On Mon, Aug 22, 2016 at 10:02 AM, Brian Grant notifications@github.com
|
Certainly anything that has already caused a security lapse would have
my vote. As well as an annotation that is difficult to explain without
swagger (init containers, pod security policy, and maybe one other)
|
Per object schemas has been suggested in the past, but one advantage Hypothetical flow (no preservation)
Hypothetical preserve old data: 2a: Beta: Adds new field to struct AlphaFeature with JSON name All internal data is ignored (no internal code ever reads from Can generate a description of API changes by structural diffs to the |
As a user, I would not feel put upon if new features had a struct name with an alpha-like prefix. Or without the prefix but activated in the minor version of a SemVer version. Injecting the new field value in an annotation, such as for the current init-container case, feels a little strange. I was surprised when I first saw this approach - but I'm not complaining - and figured there must have been a reason for it. |
Ok, so proposal for 1.5. We switch to adding new fields for annotations on at least 1 of our alpha and one of our beta fields.
|
2.7. optionally add a conversion from annotations |
Why not JSON-serialize beta fields as We need a story for simultaneously supporting alpha and beta, for On Sun, Oct 2, 2016 at 10:27 AM, Clayton Coleman notifications@github.com
|
The point of beta would be that we expect the field to be "correct". The My concern is that the gyrations we're doing around annotations and forcing Why are we simulataneously supporting alpha and beta? Isn't the point to On Oct 2, 2016, at 11:57 PM, Tim Hockin notifications@github.com wrote: Why not JSON-serialize beta fields as We need a story for simultaneously supporting alpha and beta, for On Sun, Oct 2, 2016 at 10:27 AM, Clayton Coleman notifications@github.com
— |
TL;DR; - please prioritize this discussion, as we don't have much development time left for this release. I'll be moving multiple schedulers to beta, so I'd like to have some clear decision sooner rather than later, as it seems that it's going to be rather long process... Also it'd be good to have some common decision on whether we want to have one minor release of having both alpha and beta (also beta and GA), or when graduating a feature we want to stop supporting "lower" version straight away. I guess supporting two versions for one minor release would be good for users, but it'll cause some development pain. |
I've tried to summarize the discussions with api-machinery to update guidance for alpha fields at kubernetes/community#869 |
Add language to make it explicit that annotations are not to be altered by runtimes, and should only be used for features that are opaque to the Kubernetes APIs. Unfortunately there are currently exceptions introduced in [1][1], but this change makes it clear that they are to be changed and that no more such semantic-affecting annotations should be introduced. In the spirit of the discussion and conclusion in [2][2]. Also captures the link between the annotations returned by various status queries and those supplied in associated configs. [1]: kubernetes#34819 [2]: kubernetes#30819 (comment)
Automatic merge from submit-queue Update alpha field guidance Summarizing outcome of discussions with @kubernetes/sig-api-machinery-misc ref: * https://docs.google.com/document/d/1wuoSqHkeT51mQQ7dIFhUKrdi3-1wbKrNWeIL4cKb9zU/edit# * kubernetes/kubernetes#34508 (comment) * https://www.youtube.com/watch?v=bzSK00TxEx0&list=PL69nYSiGNLP21oW3hbLyjjj4XhrwKxH2R&index=4&t=2580 (43:00-59:00) * kubernetes/kubernetes#30819
[MILESTONENOTIFIER] Milestone Labels Complete Issue label settings:
|
Should this issue still be in the v1.8 milestone? Seems like this would benefit from a definition of done before putting into a release milestone |
@erictune, @smarterclayton, @gmarek this is a daily and friendly ping from release team. Is this still relevant to 1.8? If yes, who is actively working on it? |
This doesn't seem actionable, and it seems to have significant overlap with #34508. |
I think the updated guidance to stop using annotations for alpha features stops the bleeding, and the field gate proposal captures concrete improvements that need to happen to make working with alpha fields sustainable |
Automatic merge from submit-queue Loadbalanced client src ip preservation enters beta Sounds like we're going to try out the proposal (kubernetes/kubernetes#30819 (comment)) for annotations -> fields on just one feature in 1.5 (scheduler). Or do we want to just convert to fields right now?
Our current API strategy is to add annotations for new features. These annotations are expected to overlay on top of the existing API fields, and alter system behavior in other components. Our primary reason for annotations today:
Annotations come with a set of issues:
Alpha annotations are not discoverable and do not show up in our docs - users don't know how to use the features, and we get no automatic benefits from swagger or other tools
kubectl explain
to end usersDevelopers who implement those annotations must merge the value in to the internal or external types at various points in the lifecycle - conversion, validation, in client libraries, and in nested utilities.
api.PodSpec
) must also receive a list of annotations that alter that pod spec (for things like init containers) and potentially merge thoseSome alpha features may be missed by a developer unfamiliar with the annotation - without any of the normal tools to introspect code (code completion, reflective tests on structs) it is more likely that the impact of an annotation is missed when adding new code.
The security implications of an annotation are harder to convey than a field, and code that allows annotation mutation but not field annotation can be exposed to malicious authors accidentally (bind, status, and a few other sub resources that protect spec can be abused to mutate init containers, for example).
A malicious user can introduce an annotation for an upcoming alpha feature on a cluster before the feature is introduced, which means that prior to enabling an alpha feature a cluster admin has to sweep all possible objects to ensure no dangerous annotations are set.
This occurred for init containers - podsecuritypolicy is applied at creation time, but because init containers are represented as annotations a malicious user can set an init container annotation before Kube 1.3 is rolled out, and as soon as the cluster is upgraded that container would be executed. This means that admins have to run a pre-upgrade migration to purge any dangerous / out of policy annotations.
For these reasons, I believe we should not be using annotations for alpha level fields internally, and probably not externally.
Alternative
Instead, I believe we should represent alpha level fields in our Go structs and clearly denote them as alpha (perhaps with an named prefix). Once the feature is out of alpha, we would leave the alpha level field in the external struct for at least 1 major version to allow upgraders to use that field. We would then drop the alpha field, which would clean the database of that value. Internal code would simply rename the field, and ignore the external field.
Alpha level fields would be denoted by struct tags that allowed them to show up in swagger. Once we dropped support for the field, swagger would no longer show them. We would have to have a "drop by default" rule in place for swagger validations on fields that are no longer recognized for old alpha fields that aren't supported, but that's what we want for alpha.
E.g.:
Kube 1.2:
Kube 1.3:
Kube 1.4:
Kube 1.5
The text was updated successfully, but these errors were encountered: