Skip to content

Commit 204965a

Browse files
committed
Add security considerations guide, update security model
1 parent a83607f commit 204965a

File tree

4 files changed

+176
-9
lines changed

4 files changed

+176
-9
lines changed

nav.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ nav:
88
- API Overview: concepts/api-overview.md
99
- Conformance: concepts/conformance.md
1010
- Roles and Personas: concepts/roles-and-personas.md
11+
- Security Considerations: concepts/security-considerations.md
1112
- Security Model: concepts/security-model.md
1213
- Tools: concepts/tooling.md
1314
- Use Cases: concepts/use-cases.md

nav.yml.tmpl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ nav:
88
- API Overview: concepts/api-overview.md
99
- Conformance: concepts/conformance.md
1010
- Roles and Personas: concepts/roles-and-personas.md
11+
- Security Considerations: concepts/security-considerations.md
1112
- Security Model: concepts/security-model.md
1213
- Tools: concepts/tooling.md
1314
- Use Cases: concepts/use-cases.md
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
# Gateway API security considerations
2+
3+
Gateway controllers can be deployed in a multi-tenant environment, where different
4+
namespaces are used by different users and customers.
5+
6+
Some caution should be taken by the cluster administrators and Gateway owners to
7+
provide a safer environment.
8+
9+
## Avoiding hostname/domain hijacking
10+
11+
Gateway controllers work to disambiguate and detect conflicts caused by sharing
12+
different ports, protocols, etc. between various listeners. (?)
13+
14+
Generally this conflict detection works on a first-come, first-served basis, where
15+
the first created resource wins in the conflict management.
16+
17+
The [hostname definition](../reference/spec.md#httproutespec) is a list, so given the
18+
following scenario:
19+
20+
* `Gateway` accepts routes from a set of namespaces
21+
* `HTTPRoute` with name `route1` is created on namespace `ns1`, with `creationTimestamp: 00:00:01`
22+
and defines hostname `something.tld`.
23+
* `HTTPRoute` with name `route2` is created on namespace `ns2`, with `creationTimestamp: 00:00:30
24+
and defines hostname `otherthing.tld`.
25+
26+
The owner of `route1` can hijack the domain `otherthing.tld` from `route2` because
27+
`route1` is an older resource.
28+
29+
To avoid this situation, the following actions should be taken:
30+
31+
* On shared gateways, admin SHOULD specify on the listener definitions different
32+
domains, and specific namespaces allowed to use each domain, as the example below:
33+
34+
```yaml
35+
apiVersion: gateway.networking.k8s.io/v1
36+
kind: Gateway
37+
metadata:
38+
name: gateway1
39+
spec:
40+
listeners:
41+
- hostname: "something.tld"
42+
port: 80
43+
protocol: HTTP
44+
allowedRoutes:
45+
namespaces:
46+
from: Selector
47+
selector:
48+
kubernetes.io/metadata.name: ns1
49+
```
50+
51+
* Because the number of listeners is limited on a Gateway, the administrator should
52+
instead rely on some validation (like ValidationAdmissionPolicy or some other mechanism)
53+
that limits what hostnames can be used on routes of each namespaces.
54+
* In case of `ListenerSet` (still experimental) a validation policy should also be applied.
55+
56+
### Example of a ValidatingAdmissionPolicy
57+
58+
A [ValidatingAdmissionPolicy](https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/)
59+
can be used to add rules that limits what namespaces can use what domains.
60+
61+
!!! warning
62+
The validation policy shown here **IS AN EXAMPLE** and the cluster-admin should do
63+
adjustments to their own environment! Do not copy/paste this example with proper
64+
adjustments
65+
66+
The policy exemplified here will:
67+
68+
* Read the allowed domains from a comma-separated value of the `annotation` "domains" present on the namespace.
69+
* Validate if all of the hostnames within `.spec.hostnames` are contained on this annotation.
70+
* In case any of the entries are not authorized, the policy denies its admission.
71+
72+
```yaml
73+
apiVersion: admissionregistration.k8s.io/v1
74+
kind: ValidatingAdmissionPolicy
75+
metadata:
76+
name: httproute-hostname-policy
77+
spec:
78+
failurePolicy: Fail
79+
matchConstraints:
80+
resourceRules:
81+
- apiGroups: ["gateway.networking.k8s.io"]
82+
apiVersions: ["v1", "v1beta1"]
83+
operations: ["CREATE", "UPDATE"]
84+
resources: ["httproutes"]
85+
variables:
86+
- name: allowed_hostnames_str
87+
expression: |
88+
has(namespaceObject.metadata.annotations) &&
89+
has(namespaceObject.metadata.annotations.domains) ?
90+
namespaceObject.metadata.annotations['domains'] : ''
91+
- name: allowed_hostnames_list
92+
expression: |
93+
variables.allowed_hostnames_str.split(',').
94+
map(h, h.trim()).filter(h, size(h) > 0)
95+
validations:
96+
- expression: |
97+
!has(object.spec.hostnames) ||
98+
size(object.spec.hostnames) == 0 ||
99+
object.spec.hostnames.all(hostname, hostname in variables.allowed_hostnames_list)
100+
message: "HTTPRoute validation failed. It contains unauthorized hostnames"
101+
---
102+
apiVersion: admissionregistration.k8s.io/v1
103+
kind: ValidatingAdmissionPolicyBinding
104+
metadata:
105+
name: httproute-hostname-binding
106+
spec:
107+
policyName: httproute-hostname-policy
108+
validationActions: ["Deny"]
109+
matchResources:
110+
namespaceSelector: {}
111+
```
112+
113+
Once the policy is created, the cluster-admin should explicitly allow the usage of
114+
domains with a command like `kubectl annotate ns default domains=www.dom1.tld,www.dom2.tld`
115+
116+
Additionally, when dealing with environments that provide DNS record creations,
117+
admins should be aware and limit the DNS creation based on the same constraints above.
118+
119+
## Usage of ReferenceGrant
120+
121+
Owners of resources should be aware of the usage of [ReferenceGrants](../api-types/referencegrant.md).
122+
This should be audited and limited by admins (needs some better writing here).
123+
124+
The intended use of ReferenceGrants is to allow for the *owner* of an object where
125+
Gateway API cannot change the spec (such as a Secret or Service) to have a way to
126+
allow cross-namespace use of that object for Gateway API purposes.
127+
128+
It’s intended to require that the use of an object in a Gateway API object requires
129+
both the ***referrer*** (generally the Gateway or Route) and the ***referent***
130+
(a Secret or Service) to *agree* that the reference is allowed. This means that,
131+
when the referrer and referent are owned by different people, then those two people
132+
must also agree that the reference is allowed.
133+
134+
The design of ReferenceGrant is intended to be as secure as possible by default:
135+
136+
* Without a ReferenceGrant, cross-namespace references to a Secret or Gateway
137+
(or any other resource that Gateway API does not control the spec of) MUST fail.
138+
* The ReferenceGrant MUST be created in the same namespace as the object that
139+
reference permissions are being granted to. This makes it easier to ensure that
140+
the same person owns both the referent object and the ReferenceGrant.
141+
* Most fields in the ReferenceGrant object are **required**, so that the
142+
ReferenceGrant cannot be overly broad.
143+
144+
Because of this design, ReferenceGrant owners should ensure that the reference
145+
permissions being granted are as minimal as possible.
146+
147+
* Specify `to` targets in all possible ways (`group`, `kind`, **and** `name`)
148+
* In particular, DO NOT leave `name` unspecified, even though it is optional, without a *very* good reason, as that is granting a blanket
149+
150+
151+
## Proper definition of Roles and RoleBinding
152+
153+
The creation of a new Gateway should be considered as a privileged permission.
154+
The unguarded creation of Gateways may increase costs, infrastructure modifications
155+
(like a LoadBalancer and a DNS record creation) and as in such case, admins should
156+
be aware of it and create [Roles](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole)
157+
and [RoleBindings](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#rolebinding-and-clusterrolebinding)
158+
that reflect proper user permissions.
159+
160+
Additionally, it is highly recommended that the strict permissions are given, not
161+
allowing regular users to modify a Gateway API status.
162+
163+
For more information about the security model of Gateway API, check [Security Model](security-model.md)
164+
165+
## Usage and limit of GatewayClass
166+
167+
A cluster may have different GatewayClasses, with different purposes. As an example,
168+
one GatewayClass may enforce that Gateways attached to it can only use internal load balancers.
169+
170+
Cluster admins should be aware of these requirements, and define validation
171+
policies that limit the improper attachment of a Gateway to a GatewayClass by unauthorized users.
172+
173+
A [ValidatingAdmissionPolicy](https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/)
174+
can be used to limit what namespaces can use a `GatewayClass`.

site-src/concepts/security-model.md

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,3 @@ the ReferenceGrant.
100100
For more information on ReferenceGrant, refer to our [detailed documentation
101101
for this resource](../api-types/referencegrant.md).
102102

103-
## Advanced Concept: Limiting Namespaces Where a GatewayClass Can Be Used
104-
Some infrastructure providers or cluster operators may wish to limit the
105-
namespaces where a GatewayClass can be used. At this point, we do not have a
106-
solution for this built into the API. In lieu of that, we recommend using a
107-
policy agent such as Open Policy Agent and
108-
[Gatekeeper](https://github.com/open-policy-agent/gatekeeper) to enforce these
109-
kinds of policies. For reference, we've created an [example of
110-
configuration](https://github.com/open-policy-agent/gatekeeper-library/pull/24)
111-
that could be used for this.

0 commit comments

Comments
 (0)