Skip to content
Back to skills

Helm Security Secrets

ASecurity

Kubernetes security enforcement and cryptographic secrets management for Helm charts. Covers Pod Security Admission (PSA) restricted profiles, hardened securityContext (runAsNonRoot, readOnlyRootFilesystem, allowPrivilegeEscalation), NetworkPolicies with default-deny posture, and SOPS/helm-secrets/age encryption for cryptographic materials. Use when: (1) writing pod securityContext blocks, (2) enforcing PSA restricted profiles, (3) configuring default-deny NetworkPolicies, (4) integrating SOP...

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 29, 2026
ai-agentsbashkubernetestestinggitapisecurity

Works with

  • api

Security analysis

A100/100

Scanned September 29, 2026

npx -y skills add talkops-ai/opscode --skill helm-security-secrets --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Helm Security Secrets?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Helm Security Secrets
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/talkops-ai-helm-security-secrets/badge)](https://www.skillsdirectory.com/skills/talkops-ai-helm-security-secrets)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: helm-security-secrets
description: >
  Kubernetes security enforcement and cryptographic secrets management for Helm
  charts. Covers Pod Security Admission (PSA) restricted profiles, hardened
  securityContext (runAsNonRoot, readOnlyRootFilesystem, allowPrivilegeEscalation),
  NetworkPolicies with default-deny posture, and SOPS/helm-secrets/age encryption
  for cryptographic materials. Use when: (1) writing pod securityContext blocks,
  (2) enforcing PSA restricted profiles, (3) configuring default-deny NetworkPolicies,
  (4) integrating SOPS with helm-secrets and age key pairs, (5) structuring .sops.yaml
  creation rules, (6) encrypting secrets.yaml with sops --encrypt, or (7) deploying
  with helm secrets upgrade --install. Do NOT use for chart structure (use
  helm-chart-authoring), schema validation (use helm-schema-validation), or
  testing (use helm-testing).
license: MIT
compatibility: designed for opscode
---

# Helm Security & Secrets Management

Enforce Kubernetes security standards (PSA restricted profiles, NetworkPolicies) and manage cryptographic secrets via SOPS/helm-secrets/age encryption.

---

## Core Principles

1. **Never Hardcode Secrets**: Plaintext credentials must never appear in Helm charts, values files, or version control.
2. **PSA Restricted by Default**: All pod templates must pass the Kubernetes Pod Security Admission `restricted` profile.
3. **Default-Deny Networking**: NetworkPolicies must deny all traffic by default, whitelisting only required paths.
4. **SOPS + age**: Use Mozilla SOPS with age encryption for at-rest secret protection.

---

## Pod Security Context (PSA Restricted Profile)

Every pod template MUST include a hardened `securityContext` aligned with the Kubernetes `restricted` PSA profile:

```yaml
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "my-chart.fullname" . }}
spec:
  template:
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        runAsGroup: 1000
        fsGroup: 1000
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities:
              drop:
                - ALL
          # If the application needs writable directories, use emptyDir volumes:
          volumeMounts:
            - name: tmp
              mountPath: /tmp
      volumes:
        - name: tmp
          emptyDir: {}
```

### Security Context Checklist

| Setting | Value | Purpose |
|---|---|---|
| `runAsNonRoot` | `true` | Prevents container processes from running as root |
| `runAsUser` | `1000` (or non-zero) | Explicit non-root user ID |
| `runAsGroup` | `1000` (or non-zero) | Explicit group ID |
| `readOnlyRootFilesystem` | `true` | Prevents filesystem tampering inside the container |
| `allowPrivilegeEscalation` | `false` | Blocks sudo and setuid binaries |
| `capabilities.drop` | `["ALL"]` | Drops all Linux capabilities |
| `seccompProfile.type` | `RuntimeDefault` | Applies default seccomp filtering |

---

## NetworkPolicies (Default-Deny)

Implement a default-deny posture and whitelist only required communication paths:

```yaml
# templates/networkpolicy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: {{ include "my-chart.fullname" . }}-deny-all
spec:
  podSelector:
    matchLabels:
      {{- include "my-chart.selectorLabels" . | nindent 6 }}
  policyTypes:
    - Ingress
    - Egress
  # Default: deny all ingress and egress
  ingress: []
  egress: []

---
# Allow only required ingress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: {{ include "my-chart.fullname" . }}-allow-ingress
spec:
  podSelector:
    matchLabels:
      {{- include "my-chart.selectorLabels" . | nindent 6 }}
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: ingress-nginx
      ports:
        - protocol: TCP
          port: {{ .Values.service.port }}
```

---

## SOPS / helm-secrets / age Encryption

### End-to-End Cryptographic Workflow

**Step 1: Generate age Key Pair**

```bash
age-keygen -o key.txt
# Output: public key age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

**Step 2: Create `.sops.yaml` Configuration**

Place in chart root — defines which files to encrypt and with which key:

```yaml
# .sops.yaml
creation_rules:
  - path_regex: secrets\.yaml$
    age: "age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  - path_regex: secrets/.*\.yaml$
    age: "age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

**Step 3: Create Plaintext Secrets File**

```yaml
# secrets.yaml (BEFORE encryption)
dbPassword: "SuperSecretPassword123!"
apiKey: "[REDACTED]"
tlsCert: |
  -----BEGIN CERTIFICATE-----
  MIIDXTCCAkWgAwIBAgI...
  -----END CERTIFICATE-----
```

**Step 4: Encrypt with SOPS**

```bash
sops --encrypt --in-place secrets.yaml
```

The file is now encrypted at rest — safe for version control.

**Step 5: Deploy with helm-secrets**

```bash
helm secrets upgrade --install my-release ./my-chart \
  -f secrets.yaml \
  --namespace production
```

`helm-secrets` decrypts on-the-fly during deployment, never writing plaintext to disk.

### Referencing Encrypted Values in Templates

```yaml
# templates/secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: {{ include "my-chart.fullname" . }}
type: Opaque
data:
  db-password: {{ .Values.dbPassword | b64enc | quote }}
  api-key: {{ .Values.apiKey | b64enc | quote }}
```

### Critical Rules

- **Never commit `key.txt`** (the age private key) to version control
- **Always commit `.sops.yaml`** — it defines encryption rules, not keys
- **Encrypted `secrets.yaml` is safe** for Git — the data is AES-256-GCM encrypted
- **Use `helm secrets` wrapper** for install/upgrade — not plain `helm install`

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.