Skip to content

Commit cb65606

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

File tree

4 files changed

+174
-9
lines changed

4 files changed

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