Back to skills
extension
Category: Development & EngineeringNo API key required

building-with-cloud-security

Use when implementing Kubernetes security patterns including RBAC, NetworkPolicies, Pod Security Standards, secrets management, image scanning with Trivy, Cosign signing, and Dapr security. Covers 4C model, compliance fundamentals.

personAuthor: jakexiaohubgithub

Cloud-Native Security Expertise

You are a Kubernetes security expert with production experience implementing the 4C security model (Cloud, Cluster, Container, Code). You understand both the defense-in-depth philosophy and practical implementation patterns for securing AI agent deployments on Docker Desktop Kubernetes.

When to Use This Skill

Activate when:

  • Implementing RBAC (Roles, ClusterRoles, RoleBindings, ServiceAccounts)
  • Creating NetworkPolicies (default deny, namespace isolation)
  • Configuring Pod Security Standards (PSA/PSS enforcement)
  • Managing secrets (K8s Secrets, External Secrets Operator, sealed-secrets)
  • Scanning images with Trivy or signing with Cosign/Sigstore
  • Enabling Dapr security (mTLS, API tokens, component scopes)
  • Designing for compliance (SOC2 awareness, audit logging)
  • Securing the Task API running example for production

Core Concepts

The 4C Security Model

Security is layered - each layer builds on the previous:

┌─────────────────────────────────────────┐
│              CODE                        │
│    (App-level: input validation,        │
│     dependency scanning, secrets)        │
├─────────────────────────────────────────┤
│            CONTAINER                     │
│    (Image scanning, non-root,           │
│     read-only rootfs, capabilities)      │
├─────────────────────────────────────────┤
│             CLUSTER                      │
│    (RBAC, NetworkPolicy, PSS,           │
│     secrets encryption, audit logs)      │
├─────────────────────────────────────────┤
│              CLOUD                       │
│    (Provider security, IAM,             │
│     network isolation, encryption)       │
└─────────────────────────────────────────┘

Key Principle: You cannot compensate for weak outer layers by hardening inner layers.

RBAC Decision Logic

| Scenario | Use | Why | |----------|-----|-----| | App needs read Secrets in its namespace | Role + RoleBinding | Namespace-scoped, least privilege | | CI/CD needs create Deployments across namespaces | ClusterRole + RoleBinding per namespace | Avoid ClusterRoleBinding | | Monitoring needs read all Pods cluster-wide | ClusterRole + ClusterRoleBinding | Legitimate cluster-wide read | | Each pod needs unique identity | Dedicated ServiceAccount | Never use default SA |

NetworkPolicy Patterns

Default Deny First (CRITICAL):

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

Then add explicit allow rules:

# Allow DNS (required after default deny)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
    ports:
    - protocol: UDP
      port: 53

Pod Security Standards (PSS)

Three levels enforced via namespace labels:

| Level | Use Case | Key Restrictions | |-------|----------|------------------| | Privileged | System components (CNI, storage) | None - full access | | Baseline | Development, non-sensitive workloads | Blocks hostNetwork, privileged, hostPath | | Restricted | Production workloads | + runAsNonRoot, drop ALL capabilities, seccompProfile |

Apply via labels:

kubectl label ns production \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/warn=restricted \
  pod-security.kubernetes.io/audit=restricted

Secrets Management Hierarchy

  1. K8s Secrets (base): Okay for dev, but stored in etcd (enable encryption at rest)
  2. Sealed Secrets: Encrypted secrets safe for GitOps (Bitnami project)
  3. External Secrets Operator: Sync from Vault/AWS SM/Azure KV (production recommended)

External Secrets pattern:

apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: vault-backend
  namespace: production
spec:
  provider:
    vault:
      server: "https://vault.company.com"
      path: "secret"
      version: "v2"
      auth:
        kubernetes:
          mountPath: "kubernetes"
          role: "task-api-role"

Container Security

Image Scanning with Trivy:

# Scan before push
trivy image task-api:latest --severity HIGH,CRITICAL

# In CI/CD - fail on HIGH+
trivy image task-api:latest --exit-code 1 --severity HIGH,CRITICAL

# Generate SBOM
trivy image task-api:latest --format spdx-json -o sbom.json

Image Signing with Cosign:

# Sign image (keyless with OIDC)
cosign sign ghcr.io/org/task-api:v1.0.0

# Verify before deploy
cosign verify ghcr.io/org/task-api:v1.0.0

Dapr Security

Dapr provides security between sidecars automatically:

| Feature | Default | Production | |---------|---------|------------| | mTLS between sidecars | Enabled | Verify Sentry CA | | API token auth | Disabled | Enable for exposed APIs | | Component scopes | None | Restrict per-app |

Enable API token:

# Kubernetes Secret
apiVersion: v1
kind: Secret
metadata:
  name: dapr-api-token
  namespace: dapr-system
type: Opaque
data:
  token: <base64-encoded-token>

Component scoping:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: statestore
spec:
  type: state.redis
  scopes:
  - task-api  # Only task-api can use this component

Workflow: Securing Task API

Step 1: Namespace with PSS

apiVersion: v1
kind: Namespace
metadata:
  name: task-api
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/warn: restricted

Step 2: RBAC for Task API

# ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
  name: task-api-sa
  namespace: task-api
automountServiceAccountToken: false

# Role - only what's needed
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: task-api-role
  namespace: task-api
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get", "list"]

# RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: task-api-binding
  namespace: task-api
subjects:
- kind: ServiceAccount
  name: task-api-sa
roleRef:
  kind: Role
  name: task-api-role
  apiGroup: rbac.authorization.k8s.io

Step 3: NetworkPolicy

# Default deny
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: task-api
spec:
  podSelector: {}
  policyTypes: [Ingress, Egress]

# Allow ingress from gateway only
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-gateway-ingress
  namespace: task-api
spec:
  podSelector:
    matchLabels:
      app: task-api
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          app: envoy-gateway
    ports:
    - port: 8000

# Allow DNS egress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns
  namespace: task-api
spec:
  podSelector: {}
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
    ports:
    - protocol: UDP
      port: 53

Step 4: Secure Pod Spec

apiVersion: apps/v1
kind: Deployment
metadata:
  name: task-api
  namespace: task-api
spec:
  template:
    spec:
      serviceAccountName: task-api-sa
      automountServiceAccountToken: false
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        runAsGroup: 1000
        fsGroup: 1000
        seccompProfile:
          type: RuntimeDefault
      containers:
      - name: task-api
        image: ghcr.io/org/task-api:v1.0.0@sha256:abc...
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          capabilities:
            drop: ["ALL"]
        resources:
          limits:
            memory: "256Mi"
            cpu: "500m"
          requests:
            memory: "128Mi"
            cpu: "100m"
        volumeMounts:
        - name: tmp
          mountPath: /tmp
      volumes:
      - name: tmp
        emptyDir: {}

Safety & Guardrails

NEVER

  • Use wildcards (*) in RBAC rules - explicitly list resources/verbs
  • Mount ServiceAccount tokens unless API access is required
  • Run containers as root in production
  • Store secrets in ConfigMaps or environment variables visible in manifests
  • Skip image scanning in CI/CD pipelines
  • Use privileged: true for application workloads
  • Disable mTLS between Dapr sidecars in production

ALWAYS

  • Start with default deny NetworkPolicies
  • Use dedicated ServiceAccounts per workload
  • Enable audit logging for security events
  • Pin images by digest, not just tag
  • Rotate secrets regularly (automate with ESO)
  • Apply Pod Security Standards at namespace level
  • Test security policies in staging before production

Compliance Awareness

SOC2 Relevant Controls

  • Access Control: RBAC with least privilege
  • Change Management: GitOps with signed commits
  • Audit Logging: Kubernetes audit policy enabled
  • Data Protection: Secrets encryption at rest

HIPAA Relevant Controls

  • Access: RBAC + NetworkPolicy isolation
  • Audit: Complete audit trail of data access
  • Encryption: TLS in transit, encryption at rest
  • Backup: Encrypted backups with retention

Note: Full compliance requires organizational controls beyond Kubernetes. This covers the technical implementation layer.

Docker Desktop Limitations

Docker Desktop Kubernetes has constraints:

  • No cloud IAM integration (use K8s RBAC only)
  • NetworkPolicy requires Calico or Cilium CNI (not default)
  • No cloud KMS for secrets (use sealed-secrets locally)
  • Single-node limits HA testing

For full NetworkPolicy testing:

# Install Calico on Docker Desktop
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml

References

  • Kubernetes RBAC: https://kubernetes.io/docs/reference/access-authn-authz/rbac/
  • NetworkPolicy: https://kubernetes.io/docs/concepts/services-networking/network-policies/
  • Pod Security Standards: https://kubernetes.io/docs/concepts/security/pod-security-standards/
  • External Secrets Operator: https://external-secrets.io/
  • Trivy: https://trivy.dev/
  • Cosign: https://docs.sigstore.dev/cosign/
  • Dapr Security: https://docs.dapr.io/concepts/security-concept/