Skip to content

Instantly share code, notes, and snippets.

@JoooostB
Last active January 11, 2023 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoooostB/269bc184ab114fc9bbb4b7c543247c40 to your computer and use it in GitHub Desktop.
Save JoooostB/269bc184ab114fc9bbb4b7c543247c40 to your computer and use it in GitHub Desktop.
Gatekeeper ConstraintTemplate that validates if the prefix of a namespace (all characters until first -) is equal to spec.dataFrom.*.extract.key or spec.data.*.remoteRef.key from an ExternalSecret. This ensures teams can only access their own prefixed secrets.
kind: ConstraintTemplate
apiVersion: templates.gatekeeper.sh/v1beta1
metadata:
name: externalsecretskeyprefix
annotations:
argocd.argoproj.io/sync-wave: "2"
argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true
description: >-
Validates if the prefix of a namespace (all characters until first -) is equal to spec.dataFrom.*.extract.key or spec.data.*.remoteRef.key from an ExternalSecret.
This ensures teams can only access their own secrets.
spec:
crd:
spec:
names:
kind: ExternalSecretsKeyPrefix
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package ExternalSecretsKeyPrefix
import future.keywords.in
get_prefix(ns) = prefix {
ns_split := split(ns, "-")
prefix := ns_split[0]
}
message(key, prefix) = msg {
msg := sprintf("You're not authorised to retrieve secret %v, secret must be prefixed with %v-", [key, prefix])
}
input_keys[c] {
some secret in input.review.object.spec.dataFrom
c := secret.extract
}
input_keys[c] {
some secret in input.review.object.spec.data
c := secret.remoteRef
}
violation[{"msg": msg}] {
c := input_keys[_]
not equal(get_prefix(c.key), get_prefix(input.review.object.metadata.namespace))
msg := message(c.key, get_prefix(input.review.object.metadata.namespace))
}
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: ExternalSecretsKeyPrefix
metadata:
name: external-secrets-match-key-prefix
annotations:
argocd.argoproj.io/sync-wave: "2"
argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true
spec:
match:
kinds:
- apiGroups: ["*"]
kinds: ["ExternalSecret"]
excludedNamespaces:
- kube-system
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment