securing-helm-chart-deployments について
KubernetesにHelmチャートをデプロイするチーム向けのセキュリティガイドです。チャートの完全性、レンダリング済みテンプレートのスキャン、Podのセキュリティコンテキスト、シークレット管理、最小権限のRBACを扱います。
主な機能
- 01チャートの署名と出所の検証
- 02テンプレートのレンダリングとスキャン
- 03Podのセキュリティコンテキスト設定
- 04Helm values外でのシークレット管理
- 05Helm RBAC権限の制限
活用シーン
- 01インストール前のチャート完全性確認
- 02デプロイ前の設定リスク検出
- 03ワークロードPodの安全なデフォルト設定
- 04ネームスペース単位でのデプロイ権限制限
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill securing-helm-chart-deploymentsインストール後、Claude Code で/securing-helm-chart-deploymentsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEassets/template.mdreferences/api-reference.mdstandards.mdworkflows.mdscripts/agent.pyprocess.py詳細
Helm Chart デプロイメントのセキュリティ確保
概要
Helm は Kubernetes のパッケージマネージャーです。Helm デプロイメントのセキュリティを確保するには、チャートの来歴を検証し、テンプレートをスキャンしてセキュリティ上の設定ミスを検出し、Pod のセキュリティコンテキストを強制し、シークレットを安全に管理し、Helm 操作の RBAC を制御する必要があります。
使用するタイミング
- 環境で Helm Chart デプロイメントのセキュリティ確保機能をデプロイまたは設定するとき
- コンプライアンス要件に沿ったセキュリティ管理を確立するとき
- このドメインのセキュリティアーキテクチャを構築または改善するとき
- この実装が必要なセキュリティ評価を実施するとき
前提条件
- Helm 3.12+ がインストールされていること
- クラスターにアクセスできる kubectl
- チャートの署名/検証用の GnuPG
- テンプレートのスキャン用の kubesec または checkov
チャートの来歴と整合性
Helm Chart に署名する
# Generate GPG key for signing
gpg --full-generate-key
# Package and sign chart
helm package ./mychart --sign --key "[email protected]" --keyring ~/.gnupg/pubring.gpg
# Verify chart signature
helm verify mychart-0.1.0.tgz --keyring ~/.gnupg/pubring.gpg
インストール前に Chart を検証する
# Verify chart from repository
helm pull myrepo/mychart --verify --keyring /path/to/keyring.gpg
# Check chart provenance file
cat mychart-0.1.0.tgz.prov
テンプレートのセキュリティスキャン
テンプレートをレンダリングしてスキャンする
# Render templates without deploying
helm template myrelease ./mychart --values values-prod.yaml > rendered.yaml
# Scan with kubesec
kubesec scan rendered.yaml
# Scan with checkov
checkov -f rendered.yaml --framework kubernetes
# Scan with trivy
trivy config rendered.yaml
# Scan with kube-linter
kube-linter lint rendered.yaml
設定ミスを検出するための Helm lint
# Lint chart
helm lint ./mychart --values values-prod.yaml --strict
# Lint with debug output
helm lint ./mychart --debug
values.yaml でのセキュリティコンテキストの強制
# values.yaml - Security hardened defaults
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
podSecurityContext:
seccompProfile:
type: RuntimeDefault
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
networkPolicy:
enabled: true
serviceAccount:
create: true
automountServiceAccountToken: false
image:
pullPolicy: Always
# Use digest instead of tag for immutability
# tag: "1.0.0"
# digest: "sha256:abc123..."
セキュリティコンテキストを含むテンプレート
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "mychart.fullname" . }}
spec:
template:
spec:
automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
resources:
{{- toYaml .Values.resources | nindent 12 }}
シークレット管理
外部シークレットを使用する(Helm values ではなく)
# templates/external-secret.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: {{ include "mychart.fullname" . }}-secrets
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secretsmanager
kind: ClusterSecretStore
target:
name: {{ include "mychart.fullname" . }}-secrets
data:
- secretKey: db-password
remoteRef:
key: production/database
property: password
helm-secrets プラグイン
# Install helm-secrets plugin
helm plugin install https://github.com/jkroepke/helm-secrets
# Encrypt values file
helm secrets encrypt values-secrets.yaml
# Deploy with encrypted secrets
helm secrets install myrelease ./mychart -f values.yaml -f values-secrets.yaml
# Decrypt for editing
helm secrets edit values-secrets.yaml
Helm 操作の RBAC
# helm-deployer-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: helm-deployer
namespace: production
rules:
- apiGroups: ["", "apps", "batch", "networking.k8s.io"]
resources: ["deployments", "services", "configmaps", "secrets", "ingresses", "jobs"]
verbs: ["get", "list", "create", "update", "patch", "delete"]
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: helm-deployer-binding
namespace: production
subjects:
- kind: ServiceAccount
name: helm-deployer
namespace: production
roleRef:
kind: Role
name: helm-deployer
apiGroup: rbac.authorization.k8s.io
CI/CD Helm セキュリティパイプライン
# .github/workflows/helm-security.yaml
name: Helm Chart Security
on:
pull_request:
paths: ['charts/**']
jobs:
lint-and-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Helm lint
run: helm lint ./charts/mychart --strict
- name: Render templates
run: helm template test ./charts/mychart -f charts/mychart/values.yaml > rendered.yaml
- name: Scan with kube-linter
uses: stackrox/kube-linter-action@v1
with:
directory: rendered.yaml
- name: Scan with trivy
uses: aquasecurity/trivy-action@master
with:
scan-type: config
scan-ref: rendered.yaml
- name: Scan with checkov
uses: bridgecrewio/checkov-action@master
with:
file: rendered.yaml
framework: kubernetes
ベストプラクティス
- GPG でチャートに署名し、インストール前に検証します
- デプロイ前にテンプレートをレンダリングしてスキャンし、設定ミスを検出します
- values.yaml のデフォルトでセキュリティコンテキストを強制します
- シークレットを Helm values に保存しないでください。外部シークレットまたは helm-secrets プラグインを使用します
- 不変の参照にはタグではなくイメージダイジェストを使用します
- Helm RBAC を名前空間ごとの最小権限に制限します
- requirements でチャートのバージョンを固定し、
latestは決して使用しません - CI で
--strictフラグを使って厳密に lint します - 本番環境へのデプロイ前にサードパーティ製チャートをレビューします
- インストール後のデプロイメント検証にHelm のテストフックを使用します
コメント
Markdown 対応