Work in Progress: This page is under development. Use the feedback button on the bottom right to help us improve it.

Security Hardening

Best practices for securing your Laminar deployment.

Overview

Security hardening covers:

  • Authentication & Authorization - Secure access control
  • Network Security - Traffic isolation and encryption
  • Container Security - Secure pod configuration
  • Secret Management - Protecting sensitive data
  • Compliance - Meeting regulatory requirements

Pod Security

Security Context

api:
  podSecurityContext:
    runAsNonRoot: true
    runAsUser: 1000
    runAsGroup: 1000
    fsGroup: 1000
    seccompProfile:
      type: RuntimeDefault
 
  securityContext:
    allowPrivilegeEscalation: false
    readOnlyRootFilesystem: true
    capabilities:
      drop:
        - ALL

Pod Security Standards

Apply restricted policy:

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

Network Security

Network Policies

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: laminar-api
  namespace: laminar
spec:
  podSelector:
    matchLabels:
      app: laminar-api
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              name: ingress-nginx
      ports:
        - port: 8000
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: laminar-controller
      ports:
        - port: 8001
    - to:
        - namespaceSelector: {}
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - port: 53
          protocol: UDP

TLS Configuration

api:
  ingress:
    enabled: true
    annotations:
      cert-manager.io/cluster-issuer: letsencrypt-prod
      nginx.ingress.kubernetes.io/ssl-redirect: "true"
      nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    tls:
      - secretName: laminar-tls
        hosts:
          - laminar.example.com

Secret Management

# Create storage credentials secret
kubectl create secret generic laminar-storage-credentials \
  --namespace laminar \
  --from-literal=access-key='your-access-key' \
  --from-literal=secret-key='your-secret-key'
storage:
  existingSecret: laminar-storage-credentials

RBAC

Minimal Service Account

apiVersion: v1
kind: ServiceAccount
metadata:
  name: laminar
  namespace: laminar
automountServiceAccountToken: false
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: laminar
  namespace: laminar
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get"]
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: laminar
  namespace: laminar
subjects:
  - kind: ServiceAccount
    name: laminar
    namespace: laminar
roleRef:
  kind: Role
  name: laminar
  apiGroup: rbac.authorization.k8s.io

Image Security

Use Specific Tags

api:
  image:
    repository: ghcr.io/laminar/laminar-api
    tag: "1.2.3"  # Never use 'latest'
    pullPolicy: IfNotPresent

Image Pull Secrets

kubectl create secret docker-registry regcred \
  --docker-server=ghcr.io \
  --docker-username=<username> \
  --docker-password=<token> \
  --namespace laminar
global:
  imagePullSecrets:
    - name: regcred

Scan Images

# Using Trivy
trivy image ghcr.io/laminar/laminar-api:1.2.3

Audit Logging

Enable Kubernetes Audit

# audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  - level: Metadata
    namespaces: ["laminar"]
    resources:
      - group: ""
        resources: ["secrets", "configmaps"]
  - level: RequestResponse
    namespaces: ["laminar"]
    resources:
      - group: ""
        resources: ["pods"]
    verbs: ["create", "delete"]

Application Logging

api:
  extraEnv:
    - name: LOG_LEVEL
      value: "info"
    - name: LOG_FORMAT
      value: "json"
    - name: AUDIT_LOG_ENABLED
      value: "true"

Storage Security

Encryption at Rest

RocksDB data is stored on persistent volumes. Enable encryption:

# AWS gp3 with encryption
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: gp3-encrypted
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  encrypted: "true"
  kmsKeyId: "arn:aws:kms:us-east-1:123456789:key/xxx"

Object Storage Encryption

Enable server-side encryption for checkpoints and artifacts:

storage:
  checkpoints:
    url: "s3://my-bucket/checkpoints"
    encryption: "aws:kms"
  artifacts:
    url: "s3://my-bucket/artifacts"
    encryption: "aws:kms"

Cloud Provider Security

  • Use IRSA (IAM Roles for Service Accounts)
  • Enable EKS envelope encryption
  • Use Security Groups for pods
  • Enable VPC Flow Logs
serviceAccount:
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789:role/laminar

Security Checklist

  • Pod security context configured
  • Network policies applied
  • TLS enabled for all endpoints
  • Secrets managed externally
  • RBAC with least privilege
  • Specific image tags (no latest)
  • Image scanning enabled
  • Audit logging configured
  • Storage encryption enabled
  • Cloud IAM configured

Next Steps