Skip to main content

RBAC, Security VA Access Control

Mundarija

  1. Kubernetes Security Asoslari
  2. Authentication
  3. Authorization (RBAC)
  4. ServiceAccount
  5. Security Context
  6. Pod Security Standards
  7. Network Policies
  8. Secrets Encryption

Kubernetes Security Asoslari

4C's of Cloud Native Security

Cloud → Cluster → Container → Code

1. Cloud/Infrastructure

  • Physical security
  • Network security
  • IAM (Identity and Access Management)
  • Audit logging

2. Cluster

  • API Server access control
  • etcd encryption
  • Network policies
  • RBAC

3. Container

  • Image scanning
  • Runtime security
  • Resource limits
  • Security contexts

4. Code

  • Secure coding practices
  • Dependency scanning
  • Code review
  • SAST/DAST

Defense in Depth

Ko'p qatlamli xavfsizlik:

1. Perimeter Security → Firewall, VPN
2. Network Segmentation → Network Policies
3. Authentication → Who are you?
4. Authorization → What can you do?
5. Admission Control → What resources can be created?
6. Runtime Security → What is happening?
7. Audit Logging → What happened?

API Server Security

API Server - bu Kubernetes'ning asosiy kirish nuqtasi.

Security Mechanisms:

  1. Authentication: Identity verify
  2. Authorization: Permission check
  3. Admission Control: Request validation/mutation
Request → Authentication → Authorization → Admission Control → etcd

Authentication

Ta'rif

Authentication - bu foydalanuvchi yoki service identitysini tasdiqlash.

Kubernetes'da ikki tur identity:

  1. User Accounts: Odamlar (developers, admins)
  2. Service Accounts: Podlar, applications

User Authentication

Kubernetes user account'larni o'zi boshqarmaydi. External authentication:

1. X509 Client Certificates

Certificate yaratish:

# Private key
openssl genrsa -out user.key 2048

# Certificate Signing Request (CSR)
openssl req -new -key user.key -out user.csr -subj "/CN=john/O=developers"

# Sign CSR (CA bilan)
openssl x509 -req -in user.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out user.crt -days 365

kubeconfig:

apiVersion: v1
kind: Config
clusters:
- cluster:
certificate-authority: ca.crt
server: https://kubernetes.example.com:6443
name: my-cluster
contexts:
- context:
cluster: my-cluster
user: john
name: john@my-cluster
current-context: john@my-cluster
users:
- name: john
user:
client-certificate: user.crt
client-key: user.key

Ishlatish:

kubectl --kubeconfig=john-kubeconfig.yaml get pods

2. Bearer Tokens

Static Token File:

/etc/kubernetes/token-auth.csv:

token1234567890,john,uid-john,developers

API Server flag:

--token-auth-file=/etc/kubernetes/token-auth.csv

Request:

curl -H "Authorization: Bearer token1234567890" https://kubernetes.example.com:6443/api/v1/pods

⚠️ Deprecated: Production'da ishlatilmaydi!

3. Bootstrap Tokens

Node'lar uchun temporary tokens:

apiVersion: v1
kind: Secret
metadata:
name: bootstrap-token-abc123
namespace: kube-system
type: bootstrap.kubernetes.io/token
data:
token-id: YWJjMTIz # abc123
token-secret: MDEyMzQ1Njc4OQ== # 0123456789
usage-bootstrap-authentication: dHJ1ZQ== # true

4. OpenID Connect (OIDC)

Architecture:

User → Identity Provider (Okta, Auth0, Google)
↓ (JWT token)
Kubernetes API Server

API Server flags:

--oidc-issuer-url=https://accounts.google.com
--oidc-client-id=kubernetes
--oidc-username-claim=email
--oidc-groups-claim=groups

kubeconfig:

users:
- name: john
user:
auth-provider:
name: oidc
config:
client-id: kubernetes
client-secret: secret
idp-issuer-url: https://accounts.google.com
id-token: eyJhbGciOiJSUzI1NiIs...
refresh-token: 1/abc123...

5. Webhook Token Authentication

External authentication service:

API Server flag:

--authentication-token-webhook-config-file=/etc/kubernetes/webhook-config.yaml

webhook-config.yaml:

apiVersion: v1
kind: Config
clusters:
- name: authentication-webhook
cluster:
server: https://auth.example.com/authenticate
users:
- name: webhook
contexts:
- name: webhook
context:
cluster: authentication-webhook
user: webhook
current-context: webhook

6. Service Account Tokens

Pod'lar uchun (keyinroq batafsil).

Anonymous Requests

Default: Anonymous requests enabled.

Disable:

--anonymous-auth=false

Authorization (RBAC)

Ta'rif

Authorization - bu authenticated user nima qilishi mumkinligini aniqlash.

Authorization Modes:

  1. Node: Kubelet permissions
  2. ABAC (Attribute-Based Access Control): Deprecated
  3. RBAC (Role-Based Access Control): ⭐ Most common
  4. Webhook: External authorization

API Server flag:

--authorization-mode=Node,RBAC

RBAC Asoslari

RBAC to'rtta asosiy resource'ga asoslangan:

  1. Role: Namespace-scoped permissions
  2. ClusterRole: Cluster-wide permissions
  3. RoleBinding: Role'ni user/group/SA'ga bind qilish (namespace-scoped)
  4. ClusterRoleBinding: ClusterRole'ni bind qilish (cluster-wide)

Role

Ta'rif: Namespace ichida permission'lar.

Role YAML:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: default
rules:
- apiGroups: [""] # "" core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]

Tushuntirish:

  • apiGroups: API group (core = "")
  • resources: Resource types
  • verbs: Allowed operations

Verbs:

  • get: Bitta resource o'qish
  • list: Barcha resources o'qish
  • watch: Change events
  • create: Yangi resource yaratish
  • update: Mavjud resource yangilash
  • patch: Partial update
  • delete: O'chirish
  • deletecollection: Ko'plab resources o'chirish

Multiple Resources:

rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "create", "update", "delete"]

Specific Resource Names:

rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["app-config"]
verbs: ["get", "update"]

Subresources:

rules:
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"]

RoleBinding

Ta'rif: Role'ni user/group/ServiceAccount'ga bog'laydi.

RoleBinding YAML:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: john
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io

Multiple Subjects:

subjects:
- kind: User
name: john
apiGroup: rbac.authorization.k8s.io
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
- kind: Group
name: developers
apiGroup: rbac.authorization.k8s.io
- kind: ServiceAccount
name: my-app
namespace: default

ClusterRole

Ta'rif: Cluster-wide permissions (barcha namespace'larda yoki non-namespaced resources).

ClusterRole YAML:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]

Non-namespaced Resources:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: node-reader
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list"]

Aggregated ClusterRole:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-monitoring: "true"
rules: [] # Automatically filled
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring-endpoints
labels:
rbac.example.com/aggregate-to-monitoring: "true"
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list"]

ClusterRoleBinding

Ta'rif: ClusterRole'ni cluster-wide bind qilish.

ClusterRoleBinding YAML:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io

Default ClusterRoles

Kubernetes bir nechta default ClusterRole'larni taqdim etadi:

1. cluster-admin

Superuser: Barcha resource'larga to'liq access.

kubectl create clusterrolebinding admin-binding \
--clusterrole=cluster-admin \
--user=admin

2. admin

Namespace admin: Namespace ichida barcha resource'larga access, RBAC dan tashqari.

kubectl create rolebinding admin-binding \
--clusterrole=admin \
--user=john \
--namespace=development

3. edit

Edit permissions: Read/write, lekin RBAC'ni o'zgartira olmaydi.

kubectl create rolebinding edit-binding \
--clusterrole=edit \
--user=jane \
--namespace=development

4. view

Read-only: Faqat o'qish, secrets'dan tashqari.

kubectl create rolebinding view-binding \
--clusterrole=view \
--group=developers \
--namespace=development

RBAC Best Practices

1. Least Privilege Principle

Minimum kerakli permission:

# ❌ Bad: Too broad
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]

# ✅ Good: Specific
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]

2. Namespace Isolation

Har bir namespace uchun alohida role'lar:

# Development namespace
kubectl create role dev-admin \
--verb=* \
--resource=* \
--namespace=development

# Production namespace
kubectl create role prod-viewer \
--verb=get,list \
--resource=pods,services \
--namespace=production

3. Group-Based Access

User'lar emas, group'lar:

subjects:
- kind: Group
name: developers
apiGroup: rbac.authorization.k8s.io

4. Regular Audits

# Who can access secrets?
kubectl auth can-i list secrets --as=john

# What can john do?
kubectl auth can-i --list --as=john

Testing RBAC

can-i Command

# Can I create pods?
kubectl auth can-i create pods

# Can john get secrets in default namespace?
kubectl auth can-i get secrets --as=john -n default

# Can SA my-app list pods?
kubectl auth can-i list pods --as=system:serviceaccount:default:my-app

Impersonation

# Act as john
kubectl get pods --as=john

# Act as group developers
kubectl get pods --as=john --as-group=developers

ServiceAccount

Ta'rif

ServiceAccount - bu pod'lar uchun identity.

Default ServiceAccount: Har bir namespace'da default ServiceAccount avtomatik yaratiladi.

ServiceAccount Yaratish

kubectl:

kubectl create serviceaccount my-app

YAML:

apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app
namespace: default

ServiceAccount Token

Kubernetes 1.24'dan oldin:

  • Token avtomatik Secret sifatida yaratilardi
  • Token amal qilish muddati yo'q edi

Kubernetes 1.24+:

  • Token avtomatik yaratilmaydi
  • Bound tokens (pod lifecycle'ga bog'liq)
  • TTL (Time To Live)

Manual Token Secret:

apiVersion: v1
kind: Secret
metadata:
name: my-app-token
annotations:
kubernetes.io/service-account.name: my-app
type: kubernetes.io/service-account-token

Token olish:

kubectl get secret my-app-token -o jsonpath='{.data.token}' | base64 -d

Pod'da ServiceAccount

Default ServiceAccount:

apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: app
image: myapp:1.0
# serviceAccountName mavjud bo'lmasa, default ishlatiladi

Custom ServiceAccount:

apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
serviceAccountName: my-app
containers:
- name: app
image: myapp:1.0

ServiceAccount Mounting:

Pod yaratilganda, ServiceAccount token avtomatik mount qilinadi:

/var/run/secrets/kubernetes.io/serviceaccount/
├── ca.crt
├── namespace
└── token

Pod ichidan API access:

TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
APISERVER=https://kubernetes.default.svc

curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
-H "Authorization: Bearer $TOKEN" \
$APISERVER/api/v1/namespaces/default/pods

Disable auto-mounting:

spec:
automountServiceAccountToken: false

ServiceAccount RBAC

Role:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: default
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]

RoleBinding:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: ServiceAccount
name: my-app
namespace: default
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io

Pod:

apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
serviceAccountName: my-app
containers:
- name: app
image: myapp:1.0

Endi my-pod default namespace'dagi pod'larni o'qiy oladi.


Security Context

Ta'rif

Security Context - bu pod yoki container uchun privilege va access control settings.

Pod Security Context

Pod darajasida:

apiVersion: v1
kind: Pod
metadata:
name: security-context-demo
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
fsGroupChangePolicy: "OnRootMismatch"
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: busybox
command: ["sh", "-c", "sleep 3600"]

Options:

  • runAsUser: Container user ID
  • runAsGroup: Container group ID
  • fsGroup: Volume ownership group ID
  • fsGroupChangePolicy: Volume permission change policy
  • seccompProfile: Seccomp profile
  • seLinuxOptions: SELinux options
  • supplementalGroups: Additional group IDs

Container Security Context

Container darajasida:

spec:
containers:
- name: app
image: myapp:1.0
securityContext:
runAsUser: 2000
runAsNonRoot: true
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE

Options:

  • runAsUser: Override pod runAsUser
  • runAsNonRoot: Konteyner root'dan ishlamasligini ta'minlash
  • readOnlyRootFilesystem: Root filesystem read-only
  • allowPrivilegeEscalation: Privilege escalation oldini olish
  • privileged: Privileged mode (host access)
  • capabilities: Linux capabilities

Linux Capabilities

Capabilities - bu root privileges'ni kichik bo'laklarga ajratish.

Drop all, add specific:

securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE # Port 1-1024'ga bind
- CHOWN # File ownership o'zgartirish

Common Capabilities:

  • NET_BIND_SERVICE: Privileged port'larga bind
  • SYS_TIME: System time o'zgartirish
  • SYS_ADMIN: System administration
  • NET_ADMIN: Network administration
  • CHOWN: File ownership
  • DAC_OVERRIDE: File permission bypass

Read-Only Root Filesystem

spec:
containers:
- name: app
image: nginx
securityContext:
readOnlyRootFilesystem: true
volumeMounts:
- name: cache
mountPath: /var/cache/nginx
- name: run
mountPath: /var/run
volumes:
- name: cache
emptyDir: {}
- name: run
emptyDir: {}

Write kerak bo'lgan joylar uchun volume mount qilish.

Non-Root User

Dockerfile:

FROM nginx:alpine

# Non-root user yaratish
RUN addgroup -g 1000 appuser && \
adduser -D -u 1000 -G appuser appuser

USER appuser

Pod:

spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
containers:
- name: app
image: myapp:1.0

Pod Security Standards

Ta'rif

Pod Security Standards (PSS) - bu pod security configuration'lar uchun to'plam.

3 ta level:

  1. Privileged: Unrestricted (default)
  2. Baseline: Minimally restrictive
  3. Restricted: Heavily restricted (best practice)

Pod Security Admission

Kubernetes 1.25+ built-in admission controller.

Namespace labels:

# Enforce restricted
kubectl label namespace my-namespace \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restricted

Modes:

  • enforce: Violate qilsa reject
  • audit: Audit log'ga yozish
  • warn: Warning message

Restricted Profile

Requirements:

  • runAsNonRoot: true
  • allowPrivilegeEscalation: false
  • readOnlyRootFilesystem: true (tavsiya)
  • ✅ Drop ALL capabilities
  • ✅ Seccomp profile RuntimeDefault yoki Localhost
  • hostNetwork: false
  • hostPID: false
  • hostIPC: false
  • privileged: false

Compliant Pod:

apiVersion: v1
kind: Pod
metadata:
name: restricted-pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: myapp:1.0
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL

Network Policies (Security)

Network Policy - bu pod'lar o'rtasida network traffic'ni boshqarish (firewall).

Default Deny All:

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

Allow Specific Traffic:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080

Secrets Encryption

Encryption at Rest

Default holatda Secret'lar etcd'da encrypt qilinmaydi!

EncryptionConfiguration:

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: <base64 encoded 32-byte key>
- identity: {}

API Server:

--encryption-provider-config=/etc/kubernetes/encryption-config.yaml

Encrypt existing secrets:

kubectl get secrets --all-namespaces -o json | kubectl replace -f -

Xulosa

Kubernetes Security - bu ko'p qatlamli yondashuv:

Authentication: Identity tasdiqlash ✅ Authorization (RBAC): Permission management ✅ ServiceAccount: Pod identity ✅ Security Context: Container security ✅ Pod Security Standards: Policy enforcement ✅ Network Policies: Network segmentation ✅ Secrets Encryption: Data protection