코드형 정책: 보안 규칙 자동화
PaC(코드형 정책) 보안 및 규정 준수 규칙을 정의하는 관행 버전이 지정되고 테스트 가능하며 자동으로 적용 가능한 코드입니다. 문서로 작성하는 대신 누구도 읽지 않는 PDF 정책을 PaC가 실행 가능한 코드로 변환해 적용 파이프라인과 인프라에서 자동으로.
PaC를 사용하면 "모든 컨테이너는 루트가 아닌 사용자로 실행되어야 합니다" 또는 "S3 버킷은 공개"는 비준수 배포를 차단하는 자동 제어가 됩니다. 이 인적 오류를 제거하고 지속적인 규정 준수를 보장합니다.
무엇을 배울 것인가
- 코드형 정책(Policy as Code)의 원칙과 기존 정책과의 장점
- OPA(개방형 정책 에이전트) 및 Rego 언어
- Kubernetes 정책 시행을 위한 Kyverno
- HashiCorp의 Terraform용 Sentinel
- 구성 검증을 위한 콘테스트
- 정책 테스트 및 배포
OPA: 개방형 정책 에이전트
OPA(개방형 정책 에이전트) 생태계에서 가장 널리 사용되는 정책 엔진 클라우드 네이티브. CNCF가 개발한 OPA는 선언적 언어를 사용합니다. 레고 모든 유형의 구조화된 데이터에 적용할 수 있는 정책 정의: 요청 API, Kubernetes 구성, Terraform 구성, CI/CD 파이프라인.
Rego에 정책 쓰기
# policy/kubernetes/pod-security.rego
package kubernetes.admission
# Nega i container che girano come root
deny[msg] {
input.request.kind.kind == "Pod"
container := input.request.object.spec.containers[_]
not container.securityContext.runAsNonRoot
msg := sprintf(
"Container '%s' deve avere runAsNonRoot: true",
[container.name]
)
}
# Nega immagini con tag :latest
deny[msg] {
input.request.kind.kind == "Pod"
container := input.request.object.spec.containers[_]
endswith(container.image, ":latest")
msg := sprintf(
"Container '%s' usa :latest. Specificare un tag esplicito.",
[container.name]
)
}
# Richiedi resource limits
deny[msg] {
input.request.kind.kind == "Pod"
container := input.request.object.spec.containers[_]
not container.resources.limits
msg := sprintf(
"Container '%s' deve definire resource limits (CPU e memory)",
[container.name]
)
}
OPA 정책 테스트
# policy/kubernetes/pod-security_test.rego
package kubernetes.admission
test_deny_root_container {
count(deny) > 0 with input as {
"request": {
"kind": {"kind": "Pod"},
"object": {
"spec": {
"containers": [{
"name": "app",
"image": "myapp:v1",
"securityContext": {}
}]
}
}
}
}
}
test_allow_nonroot_container {
count(deny) == 0 with input as {
"request": {
"kind": {"kind": "Pod"},
"object": {
"spec": {
"containers": [{
"name": "app",
"image": "myapp:v1",
"securityContext": {"runAsNonRoot": true},
"resources": {"limits": {"cpu": "500m", "memory": "256Mi"}}
}]
}
}
}
}
}
Kyverno: 기본 Kubernetes 정책
키베르노 Kubernetes를 위해 특별히 설계된 정책 엔진이 있습니다. 달리 Rego를 사용하는 OPA의 Kyverno는 정책을 YAML의 기본 Kubernetes 리소스로 정의합니다. 이미 Kubernetes에 익숙한 팀이 더 쉽게 채택할 수 있습니다.
# kyverno-policies/require-nonroot.yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-run-as-nonroot
annotations:
policies.kyverno.io/title: Require runAsNonRoot
policies.kyverno.io/category: Pod Security
policies.kyverno.io/severity: high
spec:
validationFailureAction: Enforce
background: true
rules:
- name: check-containers
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
Container deve girare come non-root.
Impostare securityContext.runAsNonRoot a true.
pattern:
spec:
containers:
- securityContext:
runAsNonRoot: true
---
# Richiedi registry approvati
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-image-registries
spec:
validationFailureAction: Enforce
rules:
- name: validate-registries
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Immagini devono provenire da registry approvati."
pattern:
spec:
containers:
- image: "ghcr.io/myorg/* | registry.internal.company.com/*"
콘테스트: 구성 검증
콘테스트 OPA/Rego를 사용하여 모든 유형의 구성 파일을 검증합니다. Dockerfile, Kubernetes 매니페스트, Terraform 파일, CI/CD 파이프라인. 특히 유용함 배포 전에 구성을 검증하기 위한 CI 파이프라인의 한 단계입니다.
# Installare Conftest
brew install conftest
# Validare un Dockerfile
conftest test Dockerfile --policy policy/docker/
# Validare manifest Kubernetes
conftest test k8s/ --policy policy/kubernetes/
# Validare con output strutturato
conftest test --output json terraform/ --policy policy/terraform/
# policy/docker/dockerfile.rego
package docker
# Nega Dockerfile senza USER
deny[msg] {
input[i].Cmd == "from"
not any_user_after(i)
msg := "Dockerfile deve includere l'istruzione USER per evitare l'esecuzione come root"
}
any_user_after(from_idx) {
input[j].Cmd == "user"
j > from_idx
}
# Nega immagini base :latest
deny[msg] {
input[i].Cmd == "from"
val := input[i].Value[0]
endswith(val, ":latest")
msg := sprintf("Evitare :latest nell'istruzione FROM. Usare un tag specifico: %s", [val])
}
Sentinel: Terraform 정책
보초 HashiCorp의 정책 프레임워크가 기본적으로 통합되어 있습니다. Terraform 클라우드 및 엔터프라이즈. Terraform 계획을 검증하는 정책을 정의할 수 있습니다. 적용하기 전에 규정을 준수하지 않는 리소스 생성을 방지합니다.
정책 엔진 비교
| 특성 | OPA/등록 | 키베르노 | 보초 |
|---|---|---|---|
| 범위 | 만능인 | 쿠버네티스 | HashiCorp 생태계 |
| 언어 | 레고(선언적) | K8s 네이티브 YAML | 센티넬(필수) |
| 학습 곡선 | 중간 높음 | 낮은 | 평균 |
| 특허 | 오픈 소스(아파치 2.0) | 오픈 소스(아파치 2.0) | 상업용(Terraform 클라우드) |
CI/CD 파이프라인의 정책
# .github/workflows/policy-check.yml
name: Policy Validation
on:
pull_request:
jobs:
validate-policies:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Conftest
run: |
wget -q https://github.com/open-policy-agent/conftest/releases/download/v0.46.0/conftest_0.46.0_Linux_x86_64.tar.gz
tar xzf conftest_0.46.0_Linux_x86_64.tar.gz
sudo mv conftest /usr/local/bin/
- name: Test OPA policies
run: opa test policy/ -v
- name: Validate Dockerfiles
run: conftest test Dockerfile --policy policy/docker/
- name: Validate K8s manifests
run: conftest test k8s/ --policy policy/kubernetes/
- name: Validate Terraform
run: conftest test terraform/ --policy policy/terraform/
코드형 정책 모범 사례
- 정책 버전 지정: 검토, 테스트, 릴리스를 통해 정책을 코드로 처리합니다.
- 테스트 정책: 회귀를 방지하기 위해 각 정책에 대한 단위 테스트를 작성합니다.
- 점진성: 시행(차단)으로 전환하기 전에 감사 모드(경고)로 시작합니다.
- 문서: 모든 정책에는 존재 이유에 대한 명확한 설명이 있어야 합니다.
- 빠른 피드백: 즉각적인 피드백을 위해 검증을 PR에 통합합니다.
- 처리된 예외: 만료되는 임시 예외에 대한 프로세스 제공
결론
코드형 정책(Policy as Code)은 보안 규칙을 정적 문서에서 실행 가능한 코드로 변환합니다. 자동화되었습니다. OPA, Kyverno 및 Conftest를 통해 조직은 규정 준수를 보장할 수 있습니다. 개발 프로세스를 지연시키지 않고 계속 진행됩니다.
다음 기사에서는 살펴보겠습니다. CI/CD 보안 파이프라인, 어떻게 분석하는지 빌드 및 배포 프로세스 자체 보호: 파이프라인 강화, OIDC, 최소 권한 그리고 서명된 커밋.







