# Service Account for the application
apiVersion: v1
kind: ServiceAccount
metadata:
name: web-app-sa
namespace: production
annotations:
# For AWS IAM roles (IRSA)
eks.amazonaws.com/role-arn: arn:aws:iam::123456789:role/web-app-role
automountServiceAccountToken: true
---
# Role: permissions within a namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: web-app-role
namespace: production
rules:
# Read ConfigMaps and Secrets
- apiGroups: [""]
resources: ["configmaps", "secrets"]
verbs: ["get", "list", "watch"]
# Manage pods (for debugging)
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list"]
# Read services
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "list"]
---
# Bind role to service account
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: web-app-binding
namespace: production
subjects:
- kind: ServiceAccount
name: web-app-sa
namespace: production
roleRef:
kind: Role
name: web-app-role
apiGroup: rbac.authorization.k8s.io
---
# ClusterRole for read-only cluster access
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-viewer
rules:
- apiGroups: [""]
resources: ["namespaces", "nodes", "pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch"]
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "list", "watch"]
---
# Developer role: deploy to staging
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: developer-staging
namespace: staging
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "update", "patch"]
- apiGroups: [""]
resources: ["pods", "pods/log", "pods/exec"]
verbs: ["get", "list", "create"]
- apiGroups: [""]
resources: ["services", "configmaps"]
verbs: ["get", "list"]
---
# Bind developer group
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer-staging-binding
namespace: staging
subjects:
- kind: Group
name: developers
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: developer-staging
apiGroup: rbac.authorization.k8s.io
---
# CI/CD service account (limited deploy permissions)
apiVersion: v1
kind: ServiceAccount
metadata:
name: ci-deployer
namespace: production
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: ci-deployer-role
namespace: production
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "update", "patch"]
resourceNames: ["web-app", "worker"]
- apiGroups: ["apps"]
resources: ["deployments/status"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: ci-deployer-binding
namespace: production
subjects:
- kind: ServiceAccount
name: ci-deployer
namespace: production
roleRef:
kind: Role
name: ci-deployer-role
apiGroup: rbac.authorization.k8s.io
Kubernetes RBAC (Role-Based Access Control) restricts cluster access by user, group, or service account. Roles define permissions within a single namespace using rules with apiGroups, resources, and verbs. ClusterRoles apply cluster-wide. RoleBindings link Roles to subjects (users, groups, service accounts). ClusterRoleBindings grant cluster-wide access. Service accounts provide identity for Pods. Each namespace has a default service account. Custom service accounts limit Pod permissions. automountServiceAccountToken: false prevents unnecessary token mounting. RBAC verbs include get, list, watch, create, update, patch, delete. Aggregate ClusterRoles combine multiple roles. Regular RBAC audits prevent privilege escalation.
Related snips
payload = {
sub: user.id,
iss: 'https://auth.example.com',
aud: 'codesnips-api',
exp: 15.minutes.from_now.to_i,
iat: Time.now.to_i,
JWT issuance and verification without common footguns
#!/usr/bin/env bash
set -euo pipefail
export VAULT_ADDR="https://vault.internal:8200"
export VAULT_TOKEN="${VAULT_TOKEN:?missing VAULT_TOKEN}"
Secrets management with environment isolation and Vault
import { randomBytes, createHash } from "crypto";
import jwt from "jsonwebtoken";
import { RefreshTokenStore } from "./store";
const ACCESS_SECRET = process.env.ACCESS_SECRET!;
const ACCESS_TTL = "15m";
JWT access + refresh token rotation (conceptual)
package files
import (
"context"
"time"
Presigned S3 upload URLs (AWS SDK v2)
<%# private stream: turbo signs the serialized record name %>
<%= turbo_stream_from current_user %>
<section class="notifications">
<h1>Notifications</h1>
Turbo Streams + authorization: signed per-user stream name
package api
import (
"io"
"net/http"
"os"
Safe multipart uploads using temp files (bounded memory)
Share this code
Here's the card — post it anywhere.