-
Notifications
You must be signed in to change notification settings - Fork 517
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
NE-310 Implement route admission support for HSTS header #958
Conversation
config/v1/types.go
Outdated
// tool for administrators to quickly correct mistakes. The minimum `max-age` default is -1 instead of 0. | ||
// If it is set to 1 in MaxAgePolicy, then the HSTS policy may not be deleted. | ||
// omitempty | ||
SmallestMaxAge int32 `json:"smallestMaxAge,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the doc on this field is very good. We normally try to avoid pointers because a distinction between zero and nil is painful for API consumers, but your doc here is very convincing. Do you think a *int32
provides a better experience and allows the default object (with nil
) to mean no opinion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. Made changes.
config/v1/types_ingress.go
Outdated
@@ -54,6 +54,22 @@ type IngressSpec struct { | |||
// configurable routes. | |||
// +optional | |||
ComponentRoutes []ComponentRouteSpec `json:"componentRoutes,omitempty"` | |||
|
|||
// requiredHSTSPolicies specifies HSTS policies that are required to be set on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question about the logic here. I would have expected of the slice to matter, so evaluation would look like
- check the route against each requiredHSTSPolicy index, in order
- if the namespace selector and the domain pattern matches, the first item in requiredHSTSPolicy is the one used
- the accept/reject is based on that single item
Such an ordering concept will allow for punch-throughs by placing different policy early in the slice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean you'd like to see requiredHSTSPolicy indexed by namespace selector + domain pattern?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, yes, it does use that logic. It is based on your WIP for the admission plugin. I have a slightly revised WIP for the admission plugin here: https://github.com/openshift/openshift-apiserver/pull/224/files#diff-cde26a88c8aa9772d3d1cbf96497ac0009504bc258fd662e2ad19b458dcd3d81
I'll change the comments here to make it clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, the plugin logic looks like what David describes: Pick the first matching item (matching on domain and namespace label) and admit or reject based on that item. That also seems like a good way to describe in this godoc how the list of policies is applied. As it is, the description currently in the godoc is difficult to reason about because it has many cases and describes the matching logic in terms of matching the policy as well as the domain and the namespace label.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the comments, hope it is clarified.
7e362f2
to
34abd20
Compare
config/v1/types.go
Outdated
// domainPatterns is an optional list of domains for which the desired HSTS annotations are required. | ||
// If domainPatterns is specified and a route is created with a spec.host matching one of the domains, | ||
// the route must specify the HSTS Policy components described in the matching RequiredHSTSPolicy. | ||
// If domainPatterns is empty, the specified HSTS Policy components are IGNORED. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the policy is ignored if domain patterns are empty, why would a cluster-admin want to create it? Should we simply make the minlength=1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could understand someone entering the policy, and later deleting the domainPattern as a cleanup step, but also wanting to keep it around in case a new domain wanted to use or test a proven policy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems weird to let users use the API as a note-keeping tool. I agree with David that it makes more sense to set minlength=1. Setting minlength=1 would also make this comment on "namespaceSelector" superfluous: "A domain MUST be specified in order for namespaceSelector to apply".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. I will also make DomainPatterns required.
config/v1/types.go
Outdated
type MaxAgePolicy struct { | ||
// The largest value of the RequiredHSTSPolicy max-age | ||
// -1 means no opinion | ||
// kubebuilder:validation:default=-1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add validation for a range please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is validation in the api-server PR openshift/openshift-apiserver#224
Does it also need to be here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added range validation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems as if I cannot add range validation or a default if I make this *int32
config/v1/types.go
Outdated
// If it is set to 1 in MaxAgePolicy, then the HSTS policy header may not be inactivated unless it expires. | ||
// -1 means no opinion. | ||
// kubebuilder:validation:default=-1 | ||
SmallestMaxAge int32 `json:"smallestMaxAge,omitempty" protobuf:"varint,1,opt,name=largestMaxAge"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The doc on this field reads like a very compelling reason to have a *int32
where nil and 0 mean different things. How do you feel about allowing nil and instead of -1
, "I want the default" is expressed as nil?
Similar comment here: #958 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw it before too. I'm still thinking about this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree -- will use nil instead of -1 on this. Does it sound right to make the default smallest max = 1 day and largest max = 1 year?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided it doesn't make sense to default these values. If they are missing, it indicates that the admin doesn't care.
8e06be2
to
b61c93f
Compare
config/v1/types.go
Outdated
// domainPatterns is an optional list of domains for which the desired HSTS annotations are required. | ||
// If domainPatterns is specified and a route is created with a spec.host matching one of the domains, | ||
// the route must specify the HSTS Policy components described in the matching RequiredHSTSPolicy. | ||
// If domainPatterns is empty, the specified HSTS Policy components are IGNORED. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems weird to let users use the API as a note-keeping tool. I agree with David that it makes more sense to set minlength=1. Setting minlength=1 would also make this comment on "namespaceSelector" superfluous: "A domain MUST be specified in order for namespaceSelector to apply".
config/v1/types_ingress.go
Outdated
// - If the candidate route doesn't match any requiredHSTSPolicy domainPattern and optional namespaceSelector, | ||
// then it may use any HSTS Policy annotation. | ||
// | ||
// The HSTSRequiredPolicies may be updated over time and can invalidate a route that was previously admitted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to be clear here that an existing route won't suddenly stop working, but updates to it may be rejected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Miciah what do you think of:
The HSTSRequiredPolicies may be changed over time and can therefore reject a previously admitted route if it has any invalidating changes after the HSTSRequiredPolicies are changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still worried that that could be misinterpreted. How about, "The HSTS policy configuration may be changed after routes have already been created. An update to a previously admitted route may then fail if the updated route does not conform to the updated HSTS policy configuration. However, changing the HSTS policy configuration will not cause a route that is already admitted to stop working."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
652844f
to
e3fbcd4
Compare
config/v1/types.go
Outdated
// MaxAgePolicy contains a numeric range for specifying a compliant HSTS max-age for the enclosing RequiredHSTSPolicy | ||
type MaxAgePolicy struct { | ||
// The largest allowed value (in seconds) of the RequiredHSTSPolicy max-age | ||
// This is a pointer to distinguish between value of zero and value unspecified. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are no pointers in json or yaml. Better to use more general terminology:
// This is a pointer to distinguish between value of zero and value unspecified. | |
// This value can be left unspecified, in which case no upper limit is enforced. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
471f0d3
to
4cefcc1
Compare
config/v1/types.go
Outdated
|
||
// IncludeSubDomainsPolicy contains a value for specifying a compliant HSTS includeSubdomains policy | ||
// for the enclosing RequiredHSTSPolicy | ||
// +kubebuilder:validation:Enum=RequireIncludeSubDomains;RequireNotIncludeSubDomains;NoOpinion |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// +kubebuilder:validation:Enum=RequireIncludeSubDomains;RequireNotIncludeSubDomains;NoOpinion | |
// +kubebuilder:validation:Enum=RequireIncludeSubDomains;RequireNoIncludeSubDomains;NoOpinion |
config/v1/types.go
Outdated
} | ||
|
||
// PreloadPolicy contains a value for specifying a compliant HSTS preload policy for the enclosing RequiredHSTSPolicy | ||
// +kubebuilder:validation:Enum=RequirePreload;RequireNotPreload;NoOpinion |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// +kubebuilder:validation:Enum=RequirePreload;RequireNotPreload;NoOpinion | |
// +kubebuilder:validation:Enum=RequirePreload;RequireNoPreload;NoOpinion |
/lgtm |
/assign @sttts |
// then it may use any HSTS Policy annotation. | ||
// | ||
// The HSTS policy configuration may be changed after routes have already been created. An update to a previously | ||
// admitted route may then fail if the updated route does not conform to the updated HSTS policy configuration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The admission plugin should only fail on a route update if hsts related values are changing. This statement is accurate if constrained to that case.
If you bump into some questions about how to make that ratchet, we can get into it on the admission PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you.
Thanks for the updates. Looks like a solid API. /approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: candita, deads2k, Miciah The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Route admission support for HSTS annotations on routes.
Enhancement proposal: openshift/enhancements#749