惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
N
Netflix TechBlog - Medium
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
F
Full Disclosure
V
Visual Studio Blog
aimingoo的专栏
aimingoo的专栏
NISL@THU
NISL@THU
S
Schneier on Security
T
The Exploit Database - CXSecurity.com
P
Privacy International News Feed
Latest news
Latest news
C
CERT Recently Published Vulnerability Notes
P
Privacy & Cybersecurity Law Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
C
CXSECURITY Database RSS Feed - CXSecurity.com
AWS News Blog
AWS News Blog
C
Cybersecurity and Infrastructure Security Agency CISA
L
Lohrmann on Cybersecurity
Apple Machine Learning Research
Apple Machine Learning Research
The GitHub Blog
The GitHub Blog
T
Tor Project blog
A
About on SuperTechFans
博客园 - 司徒正美
P
Proofpoint News Feed
T
Threat Research - Cisco Blogs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Jina AI
Jina AI
Microsoft Security Blog
Microsoft Security Blog
Blog — PlanetScale
Blog — PlanetScale
罗磊的独立博客
Security Latest
Security Latest
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Hugging Face - Blog
Hugging Face - Blog
云风的 BLOG
云风的 BLOG
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
L
LINUX DO - 热门话题
Know Your Adversary
Know Your Adversary
T
Tenable Blog
K
Kaspersky official blog
Simon Willison's Weblog
Simon Willison's Weblog
宝玉的分享
宝玉的分享
有赞技术团队
有赞技术团队
Cisco Talos Blog
Cisco Talos Blog
U
Unit 42
T
The Blog of Author Tim Ferriss
T
Threatpost
D
DataBreaches.Net
Engineering at Meta
Engineering at Meta
P
Palo Alto Networks Blog

OCI Registry As Storage Blog

🚀 Announcing ORAS v1.3.0 - Elevate your artifact and registry management workflows 🚀 Announcing ORAS v1.3.0-beta.3 - Enrich formatted output of oras discover Announcing ORAS v1.2.0 - OCI Spec v1.1.0 support, formatted output, and more! Lightweight Registry with Oras OCI-Layouts and Object Storage in The Cloud ORAS Welcomes New Owners, Maintainers, and Thanks Emeritus Owners ORAS 0.15 - A Fully Functional OCI Registry Client ORAS - Looking back on 2022 and forward to 2023 ORAS 0.14 and Future - Empower Container Secure Supply Chain ORAS Artifacts Draft Specification Release – Adding Secure Supply Chain Artifacts References
Bundle, test and deploy Gatekeeper policies as OCI image
Mathieu Benoit · 2023-02-13 · via OCI Registry As Storage Blog

ORAS (OCI Registry As Storage) is an important tool out there for working with OCI artifacts and OCI registries. As one of the users and advocates of ORAS, I witnessed the growing trend in both user adoption and contributions in 2022. In this blog post I will share an end-to-end scenario with OPA Gatekeeper policies and ORAS, from including the steps from bundling to deployment.

Policies are rules expressed in YAML that not only afford meeting governance requirements, but also improve the security of Kubernetes workloads and clusters. Policy engines like OPA Gatekeeper, Kyverno or even the new Kubernetes's Validating Admission Policies feature help write and enforce such policies. Once the policies are written, however, how do we easily and securely share them with different projects and teams? How do we deploy them across the fleet of clusters? How do we evaluate them as early as possible in CI/CD pipelines?

In this blog post we will demonstrate how to bundle and share Gatekeeper policies as an OCI image using the ORAS command line client, how to evaluate any Kubernetes manifests against this OCI image with the gator command line client, and how to deploy this OCI image in Kubernetes clusters, in a GitOps way.

Flow between ORAS, OCI registry, Gatekeeper and Config Sync

While we use Google Artifact Registry as the OCI registry for this example, you can use any registry supporting OCI artifacts. For the GitOps tool, we are using the OSS project: Config Sync, and you can also use it as part of the Anthos Config Management service or even use other GitOps tools supporting OCI images like FluxCD.

Create a Gatekeeper policy

Let's create a Gatekeeper policy composed by one Constraint and one ConstraintTemplate that will be leveraged throughout this blog post.

In this example, we are making sure that any non-system namespaces is leveraging the Pod Security Admission feature to enforce the Pod Security Standards.

Create a dedicated folder for the associated files:

Define the ConstraintTemplate to ensure that the Kubernetes resources contain specified labels:

cat <<EOF> policies/k8srequiredlabels.yaml

apiVersion: templates.gatekeeper.sh/v1

kind: ConstraintTemplate

metadata:

name: k8srequiredlabels

spec:

crd:

spec:

names:

kind: K8sRequiredLabels

validation:

openAPIV3Schema:

type: object

properties:

labels:

description: A list of labels and values the object must specify.

items:

properties:

allowedRegex:

description: If specified, a regular expression the annotation's

value must match. The value must contain at least one match

for the regular expression.

type: string

key:

description: The required label.

type: string

type: object

type: array

targets:

- target: admission.k8s.gatekeeper.sh

rego: |

package k8srequiredlabels

violation[{"msg": msg, "details": {"missing_labels": missing}}] {

provided := {label | input.review.object.metadata.labels[label]}

required := {label | label := input.parameters.labels[_].key}

missing := required - provided

count(missing) > 0

msg := sprintf("You must provide labels: %v for the %s: %s.", [missing, input.review.object.kind, input.review.object.metadata.name])

}

violation[{"msg": msg}] {

value := input.review.object.metadata.labels[key]

expected := input.parameters.labels[_]

expected.key == key

expected.allowedRegex != ""

not re_match(expected.allowedRegex, value)

msg := sprintf("Label %s: %s does not satisfy allowed regex: %s", [key, value, expected.allowedRegex])

}

EOF

Define the associated Constraint for the Namespaces which must have the label pod-security.kubernetes.io/enforce as the key and either baseline or restricted as the value:

cat <<EOF> policies/ns-must-have-pss-label.yaml

apiVersion: constraints.gatekeeper.sh/v1beta1

kind: K8sRequiredLabels

metadata:

name: ns-must-have-pss-label

spec:

enforcementAction: deny

match:

kinds:

- apiGroups:

- ""

kinds:

- "Namespace"

excludedNamespaces:

- config-management-monitoring

- config-management-system

- gatekeeper-system

- kube-node-lease

- kube-public

- kube-system

- resource-group-system

parameters:

labels:

- key: pod-security.kubernetes.io/enforce

allowedRegex: (baseline|restricted)

EOF

Test this policy with local files

Define a Namespace without the required label.

cat <<EOF > namespace-test.yaml

apiVersion: v1

kind: Namespace

metadata:

name: test

EOF

Let’s now locally test this Namespace against this policy with the gator CLI. This client makes it very convenient to test policies without any Kubernetes cluster!

gator test \

--filename namespace-test.yaml \

--filename policies/

Output similar to:

["ns-must-have-pss-label"] Message: "You must provide labels: {\"pod-security.kubernetes.io/enforce\"} for the Namespace: test."

Push the Gatekeeper policy as OCI image to Artifact Registry

Assuming we already have a Google Artifact Registry repository ARTIFACT_REGISTRY_REPO_NAME in the region REGION and project PROJECT_ID.

Login to Artifact Registry:

gcloud auth configure-docker ${REGION}-docker.pkg.dev

Push the Gatekeeper policy as OCI image in Google Artifact Registry repository with ORAS:

oras push \

${REGION}-docker.pkg.dev/${PROJECT_ID}/${ARTIFACT_REGISTRY_REPO_NAME}/my-policies:1.0.0 \

policies/

info

oras push with the policies/ folder will do an archive of its files.

See that the OCI image has been uploaded in the Google Artifact Registry repository:

gcloud artifacts docker images list ${REGION}-docker.pkg.dev/${PROJECT_ID}/${ARTIFACT_REGISTRY_REPO_NAME}

Test this policy with the remote OCI image

Let’s now locally test the Namespace created earlier against this policy as remote OCI image with the gator CLI. It is very convenient to share and evaluate your policies in different places (i.e. locally, during Continuous Integration pipelines, etc.)!

gator test \

--filename namespace-test.yaml \

--image ${REGION}-docker.pkg.dev/${PROJECT_ID}/${ARTIFACT_REGISTRY_REPO_NAME}/my-policies:1.0.0

note

Since gator version 3.11.0, the --image parameter has been added! We are leveraging this feature instead of pointing to the local files like we did previously with --filename policies/

Output similar to:

["ns-must-have-pss-label"] Message: "You must provide labels: {\"pod-security.kubernetes.io/enforce\"} for the Namespace: test."

Deploy this OCI image with Config Sync

Assuming we already have a Kubernetes cluster where both Config Sync and Gatekeeper should be installed.

cat << EOF | kubectl apply -f -

apiVersion: configsync.gke.io/v1beta1

kind: RootSync

metadata:

name: root-sync-policies

namespace: config-management-system

spec:

sourceFormat: unstructured

sourceType: oci

oci:

image: ${REGION}-docker.pkg.dev/${PROJECT_ID}/${ARTIFACT_REGISTRY_REPO_NAME}/my-policies:1.0.0

dir: .

auth: none

EOF

note

Here we are assuming that the OCI image is publicly exposed (auth: none) to simplify the flow of this blog post. A more secure setup can be found here showing how to privately access the Google Artifact Registry repository via Workload Identity.

Verify that the Constraint and ConstraintTemplate are actually deployed:

kubectl get constraints

kubectl get constrainttemplates

And voilà! That’s how easy it is to deploy Gatekeeper policies as OCI image in a GitOps way. Congrats!

Test this policy in the cluster

Let’s now try to deploy the Namespace defined earlier:

kubectl apply -f namespace-test.yaml

Output similar to:

Error from server (Forbidden): error when creating "namespace-test.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [ns-must-have-pss-label] You must provide labels: {"pod-security.kubernetes.io/enforce"} for the Namespace: test.

That's a wrap!

In this article, we were able to package Gatekeeper policies as an OCI image and push it to an OCI Registry, thanks to ORAS. Then, we were able to leverage the new OCI image parameter of gator test command in order to shift-left the evaluation of these policies against any Kubernetes resources outside of an actual cluster. Finally, we deployed the Gatekeeper policies as OCI image in a GitOps way.

The continuous reconciliation of GitOps reconciles between the desired state, now stored in an OCI registry, with the actual state, running in Kubernetes. Gatekeeper policies as OCI images are now just seen like any container images for your Kubernetes clusters as they are pulled from OCI registries. This continuous reconciliation from OCI registries, not interacting with Git, has a lot of benefits in terms of scalability, performance and security as you will be able to configure very fine grained access to your OCI images, across the fleet of your clusters.

For a more complete tutorial illustrating this flow with Config Sync and Policy Controller as part of the Anthos Config Management service with Google Kubernetes Engine (GKE), you could check this other blog post out.