← スキル一覧に戻る

policy-as-code
by liauw-media
Coding Prompt to kickstart a Vibe Code session
⭐ 1🍴 1📅 2026年1月24日
SKILL.md
name: policy-as-code description: "Policy as Code with OPA, Kyverno, and Checkov. Use when implementing governance, compliance automation, or security policies for infrastructure and Kubernetes."
Policy as Code
Automated policy enforcement for infrastructure, Kubernetes, and CI/CD pipelines.
When to Use
- Enforcing security policies in Kubernetes
- Validating Terraform configurations
- Implementing compliance requirements
- Pre-commit infrastructure validation
- Admission control in clusters
Tools Overview
| Tool | Target | Language | Use Case |
|---|---|---|---|
| OPA/Gatekeeper | K8s, General | Rego | Complex policies |
| Kyverno | Kubernetes | YAML | K8s-native policies |
| Checkov | IaC | Python | Terraform, CloudFormation |
| Sentinel | Terraform | Sentinel | Terraform Enterprise |
| Conftest | Config files | Rego | CI/CD validation |
OPA Gatekeeper (Kubernetes)
Installation
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/deploy/gatekeeper.yaml
Constraint Template
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
validation:
openAPIV3Schema:
type: object
properties:
labels:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
violation[{"msg": msg}] {
provided := {label | input.review.object.metadata.labels[label]}
required := {label | label := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg := sprintf("Missing required labels: %v", [missing])
}
Constraint
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: require-team-label
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Namespace"]
- apiGroups: ["apps"]
kinds: ["Deployment"]
parameters:
labels:
- "team"
- "environment"
Common Policies
# Require resource limits
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8scontainerlimits
spec:
crd:
spec:
names:
kind: K8sContainerLimits
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8scontainerlimits
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.resources.limits.cpu
msg := sprintf("Container %v has no CPU limit", [container.name])
}
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.resources.limits.memory
msg := sprintf("Container %v has no memory limit", [container.name])
}
---
# Block privileged containers
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8spsprivilegedcontainer
spec:
crd:
spec:
names:
kind: K8sPSPPrivilegedContainer
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8spsprivilegedcontainer
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
container.securityContext.privileged
msg := sprintf("Privileged container not allowed: %v", [container.name])
}
Kyverno (Kubernetes)
Installation
kubectl create -f https://github.com/kyverno/kyverno/releases/latest/download/install.yaml
Policies
# Require labels
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-labels
spec:
validationFailureAction: Enforce
rules:
- name: check-team-label
match:
any:
- resources:
kinds:
- Deployment
- StatefulSet
validate:
message: "Label 'team' is required"
pattern:
metadata:
labels:
team: "?*"
---
# Add default labels (mutating)
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-default-labels
spec:
rules:
- name: add-managed-by
match:
any:
- resources:
kinds:
- Deployment
mutate:
patchStrategicMerge:
metadata:
labels:
managed-by: kyverno
---
# Block latest tag
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-latest-tag
spec:
validationFailureAction: Enforce
rules:
- name: validate-image-tag
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Using 'latest' tag is not allowed"
pattern:
spec:
containers:
- image: "!*:latest"
---
# Require resource limits
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-resources
spec:
validationFailureAction: Enforce
rules:
- name: validate-resources
match:
any:
- resources:
kinds:
- Pod
validate:
message: "CPU and memory limits are required"
pattern:
spec:
containers:
- resources:
limits:
memory: "?*"
cpu: "?*"
requests:
memory: "?*"
cpu: "?*"
Checkov (Terraform/IaC)
Installation
pip install checkov
# or
brew install checkov
Usage
# Scan Terraform directory
checkov -d ./terraform
# Scan specific file
checkov -f main.tf
# Output formats
checkov -d . -o json
checkov -d . -o sarif
# Skip checks
checkov -d . --skip-check CKV_AWS_1,CKV_AWS_2
# Custom policies
checkov -d . --external-checks-dir ./custom-policies
Custom Policy
# custom-policies/check_s3_versioning.py
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck
from checkov.common.models.enums import CheckResult, CheckCategories
class S3Versioning(BaseResourceCheck):
def __init__(self):
name = "Ensure S3 bucket has versioning enabled"
id = "CKV_CUSTOM_1"
supported_resources = ["aws_s3_bucket"]
categories = [CheckCategories.BACKUP_AND_RECOVERY]
super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)
def scan_resource_conf(self, conf):
versioning = conf.get("versioning", [{}])
if versioning and versioning[0].get("enabled", [False])[0]:
return CheckResult.PASSED
return CheckResult.FAILED
check = S3Versioning()
.checkov.yaml
# .checkov.yaml
soft-fail: false
compact: true
framework:
- terraform
- kubernetes
skip-check:
- CKV_AWS_1 # S3 access logging
- CKV_K8S_1 # Pod security
check:
- CKV_AWS_*
- CKV_K8S_*
Conftest (CI/CD)
Installation
brew install conftest
# or
go install github.com/open-policy-agent/conftest@latest
Terraform Policy
# policy/terraform.rego
package main
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_s3_bucket"
resource.change.after.versioning[0].enabled != true
msg := sprintf("S3 bucket %v must have versioning enabled", [resource.address])
}
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_security_group_rule"
resource.change.after.cidr_blocks[_] == "0.0.0.0/0"
resource.change.after.from_port == 22
msg := sprintf("Security group rule %v allows SSH from 0.0.0.0/0", [resource.address])
}
CI/CD Integration
# .github/workflows/policy.yml
name: Policy Check
on: [pull_request]
jobs:
terraform-policy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
- name: Terraform Init
run: terraform init
- name: Terraform Plan
run: terraform plan -out=tfplan
- name: Convert to JSON
run: terraform show -json tfplan > tfplan.json
- name: Run Conftest
uses: instrumenta/conftest-action@master
with:
files: tfplan.json
policy: policy/
kubernetes-policy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Checkov
uses: bridgecrewio/checkov-action@master
with:
directory: ./kubernetes
framework: kubernetes
Pre-commit Hooks
# .pre-commit-config.yaml
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.86.0
hooks:
- id: terraform_fmt
- id: terraform_validate
- id: terraform_tflint
- id: terraform_checkov
args:
- --args=--skip-check CKV_AWS_1
- repo: https://github.com/open-policy-agent/conftest
rev: v0.46.0
hooks:
- id: conftest
args: [--policy, policy/]
Best Practices
- Start with audit mode before enforcing
- Document exceptions with rationale
- Version policies in Git
- Test policies before deployment
- Monitor policy violations for trends
- Regular policy reviews for relevance
Integration
Works with:
/k8s- Kubernetes policies/terraform- IaC validation/security- Security policies/devops- CI/CD integration
スコア
総合スコア
50/100
リポジトリの品質指標に基づく評価
✓SKILL.md
SKILL.mdファイルが含まれている
+20
○LICENSE
ライセンスが設定されている
0/10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
○最近の活動
3ヶ月以内に更新がある
0/10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
○タグ
1つ以上のタグが設定されている
0/5
レビュー
💬
レビュー機能は近日公開予定です