Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Containers Internals

ASecurity

Use when explaining or building on Linux container primitives: namespaces, cgroups v2, overlayfs, runc and the OCI spec, seccomp-bpf, capabilities, or escapes. Not for VM isolation: use qemu-kvm.

54 stars
0 votes
0 copies
0 views
Added 9/20/2026
ai-agentsshellbashnodedockerdebuggingsecurity

Security Analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned 9/20/2026

$npx -y skills add OutlineDriven/outline-driven-development --skill containers-internals --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Containers Internals?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Containers Internals
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/outlinedriven-containers-internals-outline-driven-development/badge)](https://www.skillsdirectory.com/skills/outlinedriven-containers-internals-outline-driven-development)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: containers-internals
description: 'Use when explaining or building on Linux container primitives: namespaces, cgroups v2, overlayfs, runc and the OCI spec, seccomp-bpf, capabilities, or escapes. Not for VM isolation: use qemu-kvm.'
---

# Containers internals

## Contract

| Field | Bound contract |
|---|---|
| Trigger | A container's isolation or resource limit needs explaining or debugging, a seccomp profile needs writing, a minimal container is being built without a daemon, or an escape vector needs assessing. |
| Authority | Reversible local. The write set is namespaces and cgroups created for the session under `/sys/fs/cgroup`, overlay mounts on user-named directories, an OCI bundle directory, and seccomp filters applied to processes the skill starts. Rollback is stopping those processes, unmounting, and removing the cgroup directory. Most steps need root or a user namespace. No remote mutation. |
| Side effect | Kernel namespaces, cgroups, and mounts exist while the experiment runs. |
| Done | The isolation or limit in question is reproduced with the raw primitive, the observed behavior matches the explanation, and every created object has its teardown recorded. |

## Inputs

- Question or symptom (required): an OOM kill, CPU throttling, a permission denial inside the container, a mount failure, or a concept.
- Target (optional): a running container's PID, or a rootfs directory for a manual container.
- Privilege (required to know): root, or an unprivileged user relying on user namespaces. Several steps differ.

## Procedure

1. Read and enter namespaces. Each namespace type isolates one resource. Done when: the target process's namespace inodes are listed and, when needed, a shell runs inside them.

```bash
ls -la /proc/self/ns/            # one link per namespace type
readlink /proc/1234/ns/net       # compare inodes to see who shares a namespace
nsenter -t <pid> -m -u -i -n -p bash
unshare --fork --mount-proc --pid --net --uts --ipc bash   # a manual container shell
```

| Flag | Isolates |
|---|---|
| `CLONE_NEWNS` | Mount table |
| `CLONE_NEWPID` | Process ids |
| `CLONE_NEWNET` | Network stack |
| `CLONE_NEWUTS` | Hostname and domain name |
| `CLONE_NEWIPC` | System V IPC and POSIX message queues |
| `CLONE_NEWUSER` | Uid and gid mappings |
| `CLONE_NEWCGROUP` | The cgroup root the process sees |
| `CLONE_NEWTIME` | Boot-time and monotonic clock offsets |

```c
#define _GNU_SOURCE
#include <sched.h>
#include <sys/mount.h>
#include <unistd.h>

static int container_init(void *arg)
{
    sethostname("container", 9);
    mount("proc", "/proc", "proc", 0, NULL);
    execv("/bin/sh", (char *[]){"/bin/sh", NULL});
    return 1;
}

static char stack[1024 * 1024];
/* The child stack grows down, so pass the top of the buffer. */
clone(container_init, stack + sizeof stack,
      CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWNET | SIGCHLD, NULL);
```

2. Apply a cgroups v2 limit. The unified hierarchy at `/sys/fs/cgroup` exposes one directory per group; a process joins by writing its pid to `cgroup.procs`. Done when: the limit file holds the value and `memory.events` or `cpu.stat` shows the effect under load.

```bash
mkdir /sys/fs/cgroup/mycontainer
echo $$ > /sys/fs/cgroup/mycontainer/cgroup.procs
echo 256M > /sys/fs/cgroup/mycontainer/memory.max     # hard memory limit
echo 50 > /sys/fs/cgroup/mycontainer/cpu.weight        # share relative to siblings; default 100
echo "50000 100000" > /sys/fs/cgroup/mycontainer/cpu.max   # quota and period in microseconds
echo "default 100" > /sys/fs/cgroup/mycontainer/io.weight
cat /proc/self/cgroup
cat /sys/fs/cgroup/mycontainer/memory.events           # oom and oom_kill counters
```

3. Build the filesystem with overlayfs. Reads fall through to the lower layers; writes land in the upper directory; `workdir` is overlayfs bookkeeping and must be empty and on the same filesystem as `upperdir`. Done when: the merged mount shows the union and a write appears only in `upperdir`.

```bash
mount -t overlay overlay -o lowerdir=lower1:lower2,upperdir=upper,workdir=work merged
```

Docker's `overlay2` driver keeps its layers under `/var/lib/docker/overlay2`.

4. Run the bundle with `runc`. `runc spec` writes a `config.json` whose `ociVersion` matches the installed runtime (runc 1.5.1 writes `1.3.0`); do not hand-edit that field. Edit `process.args`, `linux.namespaces`, `linux.resources`, `process.capabilities`, and `linux.seccomp`. Done when: `runc run` starts the container and `runc list` shows it.

```bash
mkdir -p mycontainer/rootfs        # populate rootfs first
runc spec -b mycontainer           # add --rootless when not root
runc run -b mycontainer mycontainer
runc list
```

5. Filter syscalls with seccomp-bpf. Done when: the filter loads and the blocked syscall returns the chosen action.

```c
#include <seccomp.h>
#include <errno.h>

scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mount), 0);
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(pivot_root), 0);
seccomp_load(ctx);
```

| Action | Effect |
|---|---|
| `SCMP_ACT_KILL_PROCESS` | Kill the whole process (`SCMP_ACT_KILL` kills only the calling thread) |
| `SCMP_ACT_ERRNO(n)` | Fail the call with `errno` `n` |
| `SCMP_ACT_TRAP` | Deliver `SIGSYS` |
| `SCMP_ACT_TRACE` | Notify a ptrace tracer |
| `SCMP_ACT_LOG` | Allow and write an audit record |
| `SCMP_ACT_NOTIFY` | Hand the call to a user-space supervisor |
| `SCMP_ACT_ALLOW` | Permit |

Docker's default profile ships in the moby repository under `profiles/seccomp/default.json`. To find the syscall a profile is missing, run the workload under `strace -f` first.

6. Drop capabilities. A container process should run as non-root with the smallest bounding set that still works. Done when: `capsh --print` or `getcap` shows only the intended capabilities.

```bash
capsh --drop=all --caps="cap_net_bind_service+eip" -- -c '/app/server'
setcap cap_net_bind_service+ep /usr/bin/myserver
getcap /usr/bin/myserver
```

7. Explain rootless mode. A user namespace maps container uid 0 to an unprivileged host uid, so root inside is an ordinary user outside. Rootless containers cannot mount most filesystems and hold no `CAP_SYS_ADMIN` on the host. Done when: `/proc/<pid>/uid_map` for the container shows the mapping.

```bash
cat /proc/self/uid_map      # "0 1000 1" maps container uid 0 to host uid 1000
```

8. Stack the escape mitigations: user namespace, seccomp, a mandatory access control profile (AppArmor or SELinux), a dropped capability set, a read-only root, `no-new-privileges`, and Landlock for filesystem scope. Known escape vectors are a mounted container-engine socket, privileged mode, kernel CVEs, and `/proc` leaks. Done when: each layer in use is named and the missing ones are listed.

```bash
docker run --read-only --cap-drop=ALL --security-opt=no-new-privileges \
  --security-opt seccomp=default.json myimage
```

For policy depth (SELinux, AppArmor, seccomp) use `kernel-security`. To trace what a container does at the syscall level, use `ebpf`. For the kernel side of cgroups and namespaces, use `kernel-internals`.

## Failure and recovery

| Failure class | Behavior |
|---|---|
| Container OOM-killed | `memory.max` was exceeded; `memory.events` shows `oom_kill`. Raise the limit or fix the leak. |
| CPU throttled | `cpu.max` quota is low; `cpu.stat` shows `nr_throttled`. Raise the quota or use `cpu.weight` for a soft share. |
| Permission denied inside the container | A needed capability was dropped. Add that one capability, not `CAP_SYS_ADMIN`. |
| Killed by seccomp at start | The profile lacks a syscall the runtime needs. Find it with `strace -f` and allow that syscall only. |
| Overlay mount fails | `workdir` is not empty or sits on a different filesystem than `upperdir`. Clean it and retry. |
| Rootless mount fails | The user namespace forbids it. Bind-mount from the host instead. |

## Output

The primitive used for each isolation or limit, the commands run, the observed effect, and the teardown list: cgroup directories to remove, mounts to unmount, and processes to stop.

Attribution

OutlineDrivenOutlineDriven
View sourceSee grades on GitHubMore from OutlineDriven →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Caveman

Terse caveman voice: answer first, fluff gone, every technical fact kept. Use for /caveman, "caveman mode", "talk like caveman", "be brief", "less tokens". Stays on until "stop caveman" or "normal mode".

1100021 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

698431 votes

Writing Skills

Create and manage Claude Code skills in HASH repository following Anthropic best practices. Use when creating new skills, modifying skill-rules.json, understanding trigger patterns, working with hooks, debugging skill activation, or implementing progressive disclosure. Covers skill structure, YAML frontmatter, trigger types (keywords, intent patterns), UserPromptSubmit hook, and the 500-line rule. Includes validation and debugging with SKILL_DEBUG. Examples include rust-error-stack, cargo-dep...

3931 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3421 votes

catchup

Recovers the conversation and failed tool calls of a previous Codex, Amp, Claude Code, Antigravity, Cline, Copilot CLI, Cursor, DeepSeek Harness, Grok Build, Kimi, OpenCode, Pi Agent, or ZCode session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", asks to recover/summarize a previous session before continuing, or asks to diagnose or report a catchup failure. Do NOT use for the current conversation, git history, or any non-agent log.

741 votes
View all in ai-agents →