## Intro

Kubernetes Security Context commands are foundational for running workloads with least privilege. A security context defines privilege and access control settings for a Pod or container, including user and group IDs, Linux capabilities, seccomp profiles, and SELinux options. This guide provides practical commands and examples to help operators, developers, and DevOps engineers configure and verify security contexts safely and effectively.

The goal is operational safety: observe before changing, limit the blast radius, use placeholders instead of secrets, verify the result, and document how to recover if the expected state is not reached. By the end of this article, you will be able to inspect current security contexts, apply appropriate settings, and troubleshoot common issues with confidence.

## Version and Environment Inventory

Before modifying any security context, you must understand your environment and current state. This section covers how to inventory your cluster, identify relevant components, and verify the Kubernetes version.

### Step 1: Check Kubernetes Version and API Support

Security context fields have evolved across Kubernetes versions. Always confirm your cluster version and API availability before applying manifests.

kubectl version --short 
 Example output:

Client Version: v1.28.2
Server Version: v1.28.3 
 Key compatibility notes:

- runAsUser , runAsGroup , fsGroup , and supplementalGroups are stable and available in all supported versions.

- seccompProfile became GA in v1.19; use securityContext.seccompProfile.type rather than annotations.

- allowPrivilegeEscalation is stable; set it to false whenever possible.

- capabilities field is stable; prefer the drop list over add .

- windowsOptions are for Windows containers (e.g., runAsUserName ).

### Step 2: Inventory Existing Security Contexts

Before changing anything, observe existing Pods and their security settings. This read-only step helps you understand the current risk posture.

List all Pods with wide output to see node placement and status:

kubectl get pods -A -o wide 
 To inspect a specific Pod's full security context, use kubectl get with YAML or JSON output. For example, to view the security context of a Pod named nginx-secure in namespace default :

kubectl get pod nginx-secure -n default -o yaml 
 Look for the securityContext section at the Pod and container levels. Here is a snippet from a Pod with a restrictive context:

spec:
 securityContext:
 runAsNonRoot: true
 runAsUser: 1000
 runAsGroup: 3000
 fsGroup: 2000
 seccompProfile:
 type: RuntimeDefault
 containers:
 - name: nginx
 image: nginx:1.25
 securityContext:
 allowPrivilegeEscalation: false
 capabilities:
 drop:
 - ALL
 runAsNonRoot: true
 runAsUser: 1000 
 You can also use kubectl describe to see events and quickly spot security-related issues, such as a Pod failing to start due to a non-root user or missing capabilities.

### Step 3: Verify Prerequisites

Security contexts rely on the container runtime and OS features. Ensure:

- The container runtime (containerd, CRI-O) supports the fields you intend to use.

- If using seccomp profiles, the profile file is present on the node or loaded as a custom resource.

- SELinux or AppArmor policies align with your settings.

- The Pod's service account has permission for any additional resources, though security context changes do not require extra RBAC.

A quick check for seccomp support:

kubectl get nodes -o jsonpath='{.items[*].metadata.name}' | xargs -I {} kubectl get node {} -o jsonpath='{.status.nodeInfo.containerRuntimeVersion}' && echo 
 Example output: containerd://1.7.2

<style>
.eno-quiz-widget{margin:2rem 0;padding:1.5rem;border-radius:12px;background:var(--eno-surface-lowest,#f7f7f8);border:1px solid var(--eno-border-soft,#e2e2e6);font-family:var(--eno-font-body,Inter,sans-serif)}
.eno-quiz-widget .eno-quiz-kicker{font-family:var(--eno-font-label,"JetBrains Mono",monospace);font-size:.75rem;letter-spacing:.05em;text-transform:uppercase;color:var(--eno-text-muted,#5f5f68);margin:0 0 .5rem}
.eno-quiz-widget .eno-quiz-question{font-family:var(--eno-font-heading,"Hanken Grotesk",sans-serif);font-size:1.0625rem;font-weight:600;margin:0 0 1rem;color:var(--eno-text-strong,#1a1a1f)}
.eno-quiz-widget .eno-quiz-options{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.5rem}
.eno-quiz-widget .eno-quiz-option{display:block;width:100%;min-height:44px;text-align:left;padding:.625rem .875rem;border-radius:8px;border:1.5px solid var(--eno-border-soft,#e2e2e6);background:#fff;font-size:.9375rem;cursor:pointer;transition:border-color var(--eno-motion-base,180ms ease-out),background var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-option:hover{border-color:var(--eno-primary,#0059bb)}
.eno-quiz-widget .eno-quiz-option:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-option[aria-pressed="true"]{border-color:var(--eno-primary,#0059bb);background:rgb(0 89 187 / 0.06)}
.eno-quiz-widget .eno-quiz-option[data-correct="true"].eno-quiz-revealed{border-color:var(--eno-success,#17803a);background:rgb(23 128 58 / 0.08)}
.eno-quiz-widget .eno-quiz-option[data-correct="false"].eno-quiz-revealed.eno-quiz-was-selected{border-color:var(--eno-error,#ba1a1a);background:var(--eno-error-soft,#ffdad6)}
.eno-quiz-widget .eno-quiz-option-icon{display:inline-block;width:1.1em;margin-right:.4em;font-weight:700}
.eno-quiz-widget .eno-quiz-submit{margin-top:1rem;min-height:44px;padding:.5rem 1.25rem;border-radius:8px;border:none;background:var(--eno-primary,#0059bb);color:#fff;font-weight:600;font-size:.9375rem;cursor:pointer;transition:opacity var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-submit:disabled{opacity:.5;cursor:not-allowed}
.eno-quiz-widget .eno-quiz-submit:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-explanation{margin-top:1rem;padding:.875rem 1rem;border-radius:8px;font-size:.9375rem;line-height:1.5;display:none}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-visible{display:block}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-correct{background:rgb(23 128 58 / 0.08);color:var(--eno-success,#17803a)}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-incorrect{background:var(--eno-error-soft,#ffdad6);color:var(--eno-error,#ba1a1a)}
@media (prefers-reduced-motion: reduce){.eno-quiz-widget *{transition:none!important}}
</style><div class="eno-quiz-widget" role="group" aria-label="Quick check question">
Quick check 1 of 2

Which of the following fields in the securityContext is used to specify the primary group ID for all processes within containers of a Pod?

- runAsUser
- runAsGroup
- fsGroup
- supplementalGroups

<button type="button" class="eno-quiz-submit" disabled>Submit</button>
<div class="eno-quiz-explanation">The passage states: &#39;The runAsGroup field specifies the primary group ID of 3000 for all processes within any containers of the Pod.&#39;</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
  document.querySelectorAll('.eno-quiz-widget:not([data-eno-quiz-bound])').forEach(function (widget) {
    widget.setAttribute('data-eno-quiz-bound', '1');
    var options = Array.prototype.slice.call(widget.querySelectorAll('.eno-quiz-option'));
    var submitBtn = widget.querySelector('.eno-quiz-submit');
    var explanation = widget.querySelector('.eno-quiz-explanation');
    var selected = null;
    options.forEach(function (opt) {
      opt.addEventListener('click', function () {
        if (widget.hasAttribute('data-eno-quiz-answered')) return;
        options.forEach(function (o) { o.setAttribute('aria-pressed', 'false'); });
        opt.setAttribute('aria-pressed', 'true');
        selected = opt;
        submitBtn.disabled = false;
      });
    });
    submitBtn.addEventListener('click', function () {
      if (!selected || widget.hasAttribute('data-eno-quiz-answered')) return;
      widget.setAttribute('data-eno-quiz-answered', '1');
      submitBtn.disabled = true;
      var correct = selected.getAttribute('data-correct') === 'true';
      options.forEach(function (o) {
        o.classList.add('eno-quiz-revealed');
        if (o === selected) o.classList.add('eno-quiz-was-selected');
        var icon = o.querySelector('.eno-quiz-option-icon');
        if (o.getAttribute('data-correct') === 'true') icon.textContent = '\u2713';
        else if (o === selected) icon.textContent = '\u2717';
      });
      explanation.classList.add('eno-quiz-visible', correct ? 'eno-quiz-correct' : 'eno-quiz-incorrect');
    });
  });
});
</script>

## Safe Configuration Path

Now that you have observed the environment, you can make minimal, justified changes. This section provides concrete examples for common security context configurations, emphasizing a least-privilege approach.

### General Principles

- Apply one change at a time.

- Always set runAsNonRoot: true unless the container genuinely needs root.

- Use specific runAsUser and runAsGroup IDs to avoid relying on image defaults.

- Drop all capabilities and add back only what is required.

- Set allowPrivilegeEscalation: false .

- Use a runtime default seccomp profile ( RuntimeDefault ) as a baseline; consider a custom profile for stricter control.

- Avoid privileged containers; if unavoidable, set privileged: false everywhere else.

### Example 1: Run as Non-Root User

A common hard requirement: the container must not run as root. Create a Pod manifest with a security context that sets a non-root user.

Save the following as nonroot-pod.yaml :

apiVersion: v1
kind: Pod
metadata:
 name: nonroot-demo
spec:
 securityContext:
 runAsNonRoot: true
 runAsUser: 1000
 runAsGroup: 3000
 fsGroup: 2000
 containers:
 - name: app
 image: alpine:3.19
 command: ["sleep", "3600"]
 securityContext:
 allowPrivilegeEscalation: false 
 Apply it:

kubectl apply -f nonroot-pod.yaml 
 Expected output:

pod/nonroot-demo created 
 Verify the Pod is running and that the container processes are not root:

kubectl exec nonroot-demo -- id 
 Expected output (if user 1000 exists in the container):

uid=1000 gid=3000 groups=3000,2000 
 If the image does not have user 1000 defined, the container may fail with container has runAsNonRoot and image will run as root , indicating you need to choose a different base image or create the user in the image.

### Example 2: Drop All Capabilities and Add Only What Is Needed

Linux capabilities grant fine-grained privileges. Dropping all and adding only necessary ones reduces risk.

Create capabilities-pod.yaml :

apiVersion: v1
kind: Pod
metadata:
 name: capabilities-demo
spec:
 containers:
 - name: net-admin
 image: alpine:3.19
 command: ["sleep", "3600"]
 securityContext:
 allowPrivilegeEscalation: false
 capabilities:
 drop:
 - ALL
 add:
 - NET_BIND_SERVICE 
 Apply and verify:

kubectl apply -f capabilities-pod.yaml
kubectl exec capabilities-demo -- capsh --print | grep Current 
 Expected output shows only the allowed capabilities, including net_bind_service .

### Example 3: Apply a Seccomp Profile

Seccomp restricts syscalls. Start with the runtime default, then consider a custom profile.

Pod-level seccomp (applies to all containers):

apiVersion: v1
kind: Pod
metadata:
 name: seccomp-demo
spec:
 securityContext:
 seccompProfile:
 type: RuntimeDefault
 containers:
 - name: app
 image: alpine:3.19
 command: ["sleep", "3600"] 
 For a stricter custom profile, create a Localhost profile on the node. Example profile denying chmod :

{
 "defaultAction": "SCMP_ACT_ERRNO",
 "architectures": ["SCMP_ARCH_X86_64"],
 "syscalls": [
 {
 "names": ["chmod", "fchmod", "fchmodat"],
 "action": "SCMP_ACT_ERRNO"
 }
 ]
} 
 Save as custom-seccomp.json on the node, then reference it:

securityContext:
 seccompProfile:
 type: Localhost
 localhostProfile: custom-seccomp.json 
 Apply and test by attempting chmod inside the container; it should fail with Operation not permitted .

### Step 4: Verify After Applying

After each change, verify the Pod starts and behaves as expected. Use kubectl get pods to check status, kubectl describe for events, and kubectl logs for application errors. For a quick functional test, use kubectl exec to run commands inside the container.

For Deployments, use kubectl rollout status to ensure the rollout completes:

kubectl rollout status deployment/nginx-secure -n default 
 Expected output: deployment "nginx-secure" successfully rolled out

## Verification and Diagnostics

This section covers how to verify that security contexts are working as intended and how to diagnose issues when they are not.

### Verify Actual Runtime Security Settings

You can inspect the effective security context of a running container by looking at its process attributes or by using kubectl exec to query the environment.

For example, to check the user and groups:

kubectl exec -it nonroot-demo -- id 
 Expected output: uid=1000 gid=3000 groups=2000 (or similar, depending on image).

To verify capabilities inside the container, use capsh (may need to install):

kubectl exec capabilities-demo -- capsh --print 
 Look for Current: capabilities line.

To check the seccomp mode, use kubectl get pod with JSONPath or inspect the container runtime. For example:

kubectl get pod seccomp-demo -o jsonpath='{.spec.securityContext.seccompProfile.type}' 
 Expected output: RuntimeDefault

### Diagnose Common Failures

1. Container fails with CreateContainerConfigError

Often caused by invalid security context fields. Use kubectl describe pod <name> to see the event. Common error: invalid value: 0: must be greater than or equal to 1 for runAsUser . Fix by setting a valid UID.

2. Pod stuck in ContainerCreating or CrashLoopBackOff

Could be due to seccomp profile not found. Check events:

kubectl describe pod seccomp-demo 
 Look for: cannot load seccomp profile . Fix by ensuring the profile file exists on the node and has correct permissions.

3. Permission denied inside container despite non-root

If the container cannot write to a volume, ensure fsGroup is set to the group that owns the volume, or use a supplemental group. For example:

securityContext:
 fsGroup: 2000
 runAsUser: 1000
 runAsGroup: 3000
 supplementalGroups: [2000] 
 4. Network binding fails

If the application needs to bind to a port below 1024, add NET_BIND_SERVICE capability as shown earlier. Alternatively, configure the app to use a higher port.

5. Container cannot setuid or perform privileged operations

This is expected when allowPrivilegeEscalation: false and capabilities are dropped. If truly needed, add the specific capability, but prefer changing the application to avoid it.

### Logging and Monitoring

Security context failures often surface in container logs or events. Use kubectl logs --previous to see the last logs of a crashed container:

kubectl logs nonroot-demo --previous 
 For ongoing monitoring, consider setting up audit logging or a policy engine like OPA Gatekeeper or Kyverno to enforce security contexts.

<style>
.eno-quiz-widget{margin:2rem 0;padding:1.5rem;border-radius:12px;background:var(--eno-surface-lowest,#f7f7f8);border:1px solid var(--eno-border-soft,#e2e2e6);font-family:var(--eno-font-body,Inter,sans-serif)}
.eno-quiz-widget .eno-quiz-kicker{font-family:var(--eno-font-label,"JetBrains Mono",monospace);font-size:.75rem;letter-spacing:.05em;text-transform:uppercase;color:var(--eno-text-muted,#5f5f68);margin:0 0 .5rem}
.eno-quiz-widget .eno-quiz-question{font-family:var(--eno-font-heading,"Hanken Grotesk",sans-serif);font-size:1.0625rem;font-weight:600;margin:0 0 1rem;color:var(--eno-text-strong,#1a1a1f)}
.eno-quiz-widget .eno-quiz-options{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.5rem}
.eno-quiz-widget .eno-quiz-option{display:block;width:100%;min-height:44px;text-align:left;padding:.625rem .875rem;border-radius:8px;border:1.5px solid var(--eno-border-soft,#e2e2e6);background:#fff;font-size:.9375rem;cursor:pointer;transition:border-color var(--eno-motion-base,180ms ease-out),background var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-option:hover{border-color:var(--eno-primary,#0059bb)}
.eno-quiz-widget .eno-quiz-option:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-option[aria-pressed="true"]{border-color:var(--eno-primary,#0059bb);background:rgb(0 89 187 / 0.06)}
.eno-quiz-widget .eno-quiz-option[data-correct="true"].eno-quiz-revealed{border-color:var(--eno-success,#17803a);background:rgb(23 128 58 / 0.08)}
.eno-quiz-widget .eno-quiz-option[data-correct="false"].eno-quiz-revealed.eno-quiz-was-selected{border-color:var(--eno-error,#ba1a1a);background:var(--eno-error-soft,#ffdad6)}
.eno-quiz-widget .eno-quiz-option-icon{display:inline-block;width:1.1em;margin-right:.4em;font-weight:700}
.eno-quiz-widget .eno-quiz-submit{margin-top:1rem;min-height:44px;padding:.5rem 1.25rem;border-radius:8px;border:none;background:var(--eno-primary,#0059bb);color:#fff;font-weight:600;font-size:.9375rem;cursor:pointer;transition:opacity var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-submit:disabled{opacity:.5;cursor:not-allowed}
.eno-quiz-widget .eno-quiz-submit:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-explanation{margin-top:1rem;padding:.875rem 1rem;border-radius:8px;font-size:.9375rem;line-height:1.5;display:none}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-visible{display:block}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-correct{background:rgb(23 128 58 / 0.08);color:var(--eno-success,#17803a)}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-incorrect{background:var(--eno-error-soft,#ffdad6);color:var(--eno-error,#ba1a1a)}
@media (prefers-reduced-motion: reduce){.eno-quiz-widget *{transition:none!important}}
</style><div class="eno-quiz-widget" role="group" aria-label="Quick check question">
Quick check 2 of 2

According to the article, which seccomp profile type became GA in Kubernetes v1.19, and should be used instead of annotations?

- RuntimeDefault
- Localhost
- Unconfined
- Custom

<button type="button" class="eno-quiz-submit" disabled>Submit</button>
<div class="eno-quiz-explanation">The article says: &#39;seccompProfile became GA in v1.19; use securityContext.seccompProfile.type rather than annotations.&#39;</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
  document.querySelectorAll('.eno-quiz-widget:not([data-eno-quiz-bound])').forEach(function (widget) {
    widget.setAttribute('data-eno-quiz-bound', '1');
    var options = Array.prototype.slice.call(widget.querySelectorAll('.eno-quiz-option'));
    var submitBtn = widget.querySelector('.eno-quiz-submit');
    var explanation = widget.querySelector('.eno-quiz-explanation');
    var selected = null;
    options.forEach(function (opt) {
      opt.addEventListener('click', function () {
        if (widget.hasAttribute('data-eno-quiz-answered')) return;
        options.forEach(function (o) { o.setAttribute('aria-pressed', 'false'); });
        opt.setAttribute('aria-pressed', 'true');
        selected = opt;
        submitBtn.disabled = false;
      });
    });
    submitBtn.addEventListener('click', function () {
      if (!selected || widget.hasAttribute('data-eno-quiz-answered')) return;
      widget.setAttribute('data-eno-quiz-answered', '1');
      submitBtn.disabled = true;
      var correct = selected.getAttribute('data-correct') === 'true';
      options.forEach(function (o) {
        o.classList.add('eno-quiz-revealed');
        if (o === selected) o.classList.add('eno-quiz-was-selected');
        var icon = o.querySelector('.eno-quiz-option-icon');
        if (o.getAttribute('data-correct') === 'true') icon.textContent = '\u2713';
        else if (o === selected) icon.textContent = '\u2717';
      });
      explanation.classList.add('eno-quiz-visible', correct ? 'eno-quiz-correct' : 'eno-quiz-incorrect');
    });
  });
});
</script>

## Failure Modes and Recovery

Even with careful planning, things can go wrong. This section outlines common failure scenarios, their symptoms, and recovery steps.

### Scenario 1: Pod Refuses to Start Due to Security Context

Symptom: Pod status is CreateContainerConfigError or Error .

Diagnosis: Run kubectl describe pod <name> and look for events indicating invalid field values, missing seccomp profile, or unsupported options.

Recovery: Edit the Pod or Deployment to correct the security context. For example, if runAsUser: 0 with runAsNonRoot: true , change runAsUser to a non-zero UID or remove runAsNonRoot . Then delete and recreate the Pod (or rollout the Deployment).

### Scenario 2: Application Fails at Runtime Due to Missing Permissions

Symptom: Container starts but application exits with permission errors or crashes.

Diagnosis: Check container logs with kubectl logs <pod> . Look for messages like "permission denied" or "operation not permitted".

Recovery: Determine which capability or user change is needed. Grant the minimal additional privilege. For example, if the app needs to change system time, add SYS_TIME capability. Update the manifest and apply.

### Scenario 3: Rollout of a Security Context Change Causes Downtime

Symptom: After updating a Deployment with a new security context, new Pods fail and old Pods are terminated, leaving no available replicas.

Diagnosis: Check kubectl rollout status deployment/<name> for failure message. Inspect new Pods with kubectl describe and kubectl logs .

Recovery: Immediately rollback to the previous revision:

kubectl rollout undo deployment/nginx-secure 
 Then debug the issue in a separate namespace or with a single Pod before reapplying.

### Scenario 4: Seccomp Profile Blocks Required Syscalls

Symptom: Container fails with an errno (often EPERM or EACCES ) on a specific operation.

Diagnosis: Check application logs or use strace if available. Also, verify the applied seccomp profile: kubectl get pod <name> -o jsonpath='{.spec.securityContext.seccompProfile}' .

Recovery: Modify the custom seccomp profile to allow the needed syscall, or temporarily switch to RuntimeDefault for testing. Reload the profile and restart the Pod.

### General Recovery Best Practices

- Always have a rollback plan: use versioned manifests, GitOps, or at least kubectl rollout undo .

- Test changes in a staging environment first.

- Keep a backup of the original pod spec: kubectl get pod <name> -o yaml > pod-backup.yaml before editing.

- Document the failure and recovery in your runbook.

## Operations Checklist

Use the following checklist before and after modifying security contexts in production.

### Before Applying Changes

- [ ] Confirm Kubernetes version supports the security context fields you plan to use.

- [ ] Check current security context: kubectl get pod <name> -o yaml .

- [ ] Identify the container's runtime user and group: kubectl exec -- id (if running).

- [ ] List current capabilities: kubectl exec -- capsh --print (if available).

- [ ] Verify seccomp profile status: kubectl get pod -o jsonpath='{.spec.securityContext.seccompProfile}' .

- [ ] Back up the Pod/Deployment YAML: kubectl get -o yaml > backup.yaml .

- [ ] Determine the minimum required privileges (user, capabilities, etc.) by consulting application documentation or testing locally.

- [ ] Prepare a rollback command: kubectl rollout undo deployment/ or keep original YAML ready.

- [ ] Notify relevant team members about the change window.

### After Applying Changes

- [ ] Check Pod status: kubectl get pods -n -o wide .

- [ ] Verify the security context is set correctly: kubectl get pod -o yaml | grep -A10 securityContext .

- [ ] Confirm the container runs with the expected user: kubectl exec -- id .

- [ ] Validate capabilities: kubectl exec -- capsh --print (if available).

- [ ] Check application logs for errors: kubectl logs .

- [ ] Test critical functionality (e.g., an HTTP health check).

- [ ] Monitor for a few minutes: kubectl get pods -w .

- [ ] Update documentation and runbooks with the new configuration.

- [ ] Remove any temporary diagnostic tools or permissions.

### Example Checklist Filled for a Real Workload

 Assume you are securing an Nginx deployment in namespace web .

- Current state: Pod nginx-6d4b7c9f8-abcde running as root, no seccomp, all capabilities.

- Desired state: Run as UID 1000, drop all capabilities, seccomp RuntimeDefault.

- Backup: kubectl get deployment nginx -n web -o yaml > nginx-deployment-backup.yaml .

- Apply change: Edit deployment to add security context.

- Rollout: kubectl rollout status deployment/nginx -n web .

- Verify: kubectl exec -n web <new-pod> -- id returns uid=1000 .

- Test: curl the service; expect HTTP 200.

- Rollback if needed: kubectl rollout undo deployment/nginx -n web .

Keep this checklist as a template and adapt it to your workflow.

## Conclusion

Kubernetes Security Context commands are essential for hardening your workloads. By following a structured approach—inventorying the environment, making minimal changes, verifying outcomes, and planning for recovery—you can reduce the attack surface without sacrificing functionality.

Start with the basics: run containers as non-root, drop unnecessary capabilities, and enforce a seccomp profile. Use the commands and examples in this guide to inspect and adjust your security contexts safely. Remember that security is an ongoing process; regularly review your configurations and stay updated with Kubernetes releases.

For further learning, explore Kubernetes documentation on Pod Security Standards, Pod Security Admission, and tools like kube-bench for auditing your cluster's security posture.