41 lines
1.6 KiB
Rego
41 lines
1.6 KiB
Rego
package bluejayinfra.public_readwrite_allowlist
|
|
|
|
# Public hosts that allow a tightly bounded write surface in addition to
|
|
# GET/HEAD. updatecenter.iamworkin.lan accepts POST /api/v1/checkin/{id}
|
|
# (bootstrap-JWT) so its allowlist is GET||HEAD||POST||OPTIONS — but
|
|
# PUT/PATCH/DELETE must still 404 at the route. Any host in this set MUST
|
|
# include all four required methods AND MUST NOT include any forbidden
|
|
# method.
|
|
public_readwrite_hosts := {
|
|
"updatecenter.iamworkin.lan",
|
|
"updates.iamworkin.lan",
|
|
"update.flowercore.io",
|
|
"updates.flowercore.io",
|
|
}
|
|
|
|
required_methods := {"GET", "HEAD", "POST", "OPTIONS"}
|
|
|
|
forbidden_methods := {"PUT", "PATCH", "DELETE"}
|
|
|
|
deny[msg] {
|
|
input.kind == "IngressRoute"
|
|
route := input.spec.routes[_]
|
|
match := object.get(route, "match", "")
|
|
host := public_readwrite_hosts[_]
|
|
contains(match, sprintf("Host(`%s`)", [host]))
|
|
required := required_methods[_]
|
|
not contains(match, sprintf("Method(`%s`)", [required]))
|
|
msg := sprintf("IngressRoute %s/%s is missing required Method(%s) for public read-write host %s", [input.metadata.namespace, input.metadata.name, required, host])
|
|
}
|
|
|
|
deny[msg] {
|
|
input.kind == "IngressRoute"
|
|
route := input.spec.routes[_]
|
|
match := object.get(route, "match", "")
|
|
host := public_readwrite_hosts[_]
|
|
contains(match, sprintf("Host(`%s`)", [host]))
|
|
forbidden := forbidden_methods[_]
|
|
contains(match, sprintf("Method(`%s`)", [forbidden]))
|
|
msg := sprintf("IngressRoute %s/%s must not include Method(%s) on public read-write host %s", [input.metadata.namespace, input.metadata.name, forbidden, host])
|
|
}
|