Home Technical Support Lab Troubleshooting Guide: Seccomp Profiles, Dockerfile Security (Dockle), and Cosign Image Signing

Lab Troubleshooting Guide: Seccomp Profiles, Dockerfile Security (Dockle), and Cosign Image Signing

Last updated on Jan 06, 2026

Lab Troubleshooting Guide: Seccomp Profiles, Dockerfile Security (Dockle), and Cosign Image Signing

In DevSecOps labs you’ll often encounter three recurring challenges: limiting system calls with a seccomp profile, identifying security gaps in a Dockerfile using Dockle, and verifying container signatures with Cosign. This guide walks you through each problem, explains why you might see unexpected behavior, and provides step‑by‑step fixes you can apply right away.


1. Seccomp Profile Not Blocking Expected System Calls

1.1 What the lab asks you to do

The challenge requires you to create a seccomp JSON profile that blocks specific syscalls (e.g., mkdir, chown, chmod). When the profile is applied, attempts to run those calls inside the container should fail with “Operation not permitted.”

1.2 Why chown and chmod appear to succeed

Scenario Command executed Expected result Actual result Why it happens
Block mkdir only adduser abc (creates home dir) mkdir /home/abc fails → user creation aborts Fails as expected The blocked mkdir syscall stops the creation of the home directory.
Block chown only adduser abc (creates home dir, then chown) chown 1000:1000 /home/abc fails → user creation aborts Fails as expected The chown syscall is denied, so ownership cannot be set.
Block chmod only adduser abc (creates home dir, then chmod) chmod 488 /home/abc fails → user creation aborts Fails as expected The chmod syscall is denied, preventing permission changes.
No syscalls blocked adduser abc All steps succeed Success No restrictions are in place.

If you see no error when running chown or chmod, it usually means those syscalls are not actually blocked in your profile. Common reasons:

  1. Incorrect JSON syntax – a misplaced comma or wrong field name causes the rule to be ignored.
  2. Wrong architecture field – seccomp profiles are architecture‑specific ("arch": "SCMP_ARCH_X86_64"). Using the wrong value makes the rule ineffective.
  3. Profile not mounted – the container must be started with --security-opt seccomp=./myprofile.json. Forgetting this flag leaves the default profile in place.

1.3 How to verify your profile

  1. Inspect the running container

    docker inspect <container-id> | grep SeccompProfilePath
    

    The output should point to the JSON file you supplied.

  2. Test each syscall directly

    docker run --rm --security-opt seccomp=./myprofile.json \
        alpine:latest sh -c "mkdir /tmp/test && echo ok"
    

    Replace mkdir with chown or chmod to confirm they are blocked.

  3. Use strace for debugging (optional)

    docker run --rm --security-opt seccomp=./myprofile.json \
        -v /usr/bin/strace:/usr/bin/strace \
        alpine:latest strace -e trace=%file -f sh -c "adduser abc"
    

    Look for EACCES on the blocked syscall.

1.4 Quick checklist for a working seccomp profile

  • ✅ JSON is valid (run jq . myprofile.json to confirm).
  • ✅ Architecture matches the host (SCMP_ARCH_X86_64 for most Linux hosts).
  • ✅ Each rule includes "action": "SCMP_ACT_ERRNO" (or SCMP_ACT_KILL) and the correct "names": ["mkdir"] etc.
  • ✅ Container started with --security-opt seccomp=./myprofile.json.

2. Analyzing a Dockerfile with Dockle (Without Hints)

2.1 What Dockle does

Dockle is a static analysis tool that scans a Docker image (or Dockerfile) for best‑practice security issues: unnecessary packages, insecure permissions, use of the root user, missing HEALTHCHECK, etc.

2.2 Step‑by‑step manual inspection

  1. Clone the repository

    git clone https://github.com/goodwithtech/dockle-ci-test.git
    cd dockle-ci-test
    
  2. Open the Dockerfile and look for red flags:

    FROM python:3.9-slim
    RUN apt-get update && apt-get install -y \
        curl \
        git \
        && rm -rf /var/lib/apt/lists/*        # ✅ Clean up caches
    USER root                                 # ⚠️ Running as root
    WORKDIR /app
    COPY . /app
    RUN pip install --no-cache-dir -r requirements.txt
    EXPOSE 8000
    CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
    

    Potential issues

    • Root user: Switch to a non‑privileged user (USER appuser).
    • Missing HEALTHCHECK: Add a health endpoint to detect crashes.
    • Unpinned packages: Pin versions in requirements.txt to avoid supply‑chain attacks.
    • Excessive permissions: Ensure copied files have least‑privilege permissions (chmod 644 for code, chmod 600 for secrets).
  3. Apply best‑practice fixes

    FROM python:3.9-slim
    RUN apt-get update && apt-get install -y --no-install-recommends \
        curl \
        git && rm -rf /var/lib/apt/lists/*
    
    # Create a non‑root user
    RUN groupadd -r app && useradd -r -g app appuser
    WORKDIR /app
    COPY --chown=app:app . /app
    
    RUN pip install --no-cache-dir -r requirements.txt
    EXPOSE 8000
    
    HEALTHCHECK --interval=30s --timeout=5s \
        CMD curl -f http://localhost:8000/health || exit 1
    
    USER appuser
    CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
    
  4. Run Dockle locally (optional) to confirm the fixes:

    dockle build -t mysecureimage .
    

2.3 Key takeaways

  • Never run containers as root unless absolutely necessary.
  • Pin third‑party dependencies and keep the base image up‑to‑date.
  • Add a HEALTHCHECK to let orchestrators detect unhealthy containers.
  • Set file ownership and permissions at build time (--chown, chmod).

3. Cosign Verification Failing – “No Matching Signatures”

3.1 What the error means

Error: no matching signatures: signature not found in transparency log

Cosign looks for a signature attached to the image and, optionally, a record in the Rekor transparency log. If neither exists, verification stops with the message above.

3.2 Common causes

Cause Symptoms Fix
Image was not signed or signed with a different key cosign verify returns “no matching signatures”. Re‑run cosign sign --key <private-key> <image> and confirm the command succeeds.
Wrong image reference (registry, tag, or digest) Verification points to an image that has no signature. Use the exact reference shown after signing (e.g., harbor-wlye1f2u.lab.practical-devsecops.training/library/django.nv@sha256:…).
Transparency log disabled or network blocked Cosign cannot write/read Rekor entries. Ensure outbound HTTPS to rekor.sigstore.dev (or your private Rekor) is allowed, or add --skip-verify for a local-only check.
Public key mismatch Cosign finds a signature but cannot verify it. Verify you are using the same public key (cosign.pub) that matches the private key used to sign.

3.3 Step‑by‑step resolution

  1. Confirm you have a private key (cosign.key) and its public counterpart (cosign.pub).

  2. Sign the image (replace placeholders with your actual registry and tag):

    cosign sign --key cosign.key \
        harbor-wlye1f2u.lab.practical-devsecops.training/library/django.nv:1.0
    

    Expected output: a base64‑encoded signature stored in the image’s OCI manifest and a Rekor entry.

  3. Verify the signature using the public key:

    cosign verify --key cosign.pub \
        harbor-wlye1f2u.lab.practical-devsecops.training/library/django.nv:1.0
    

    You should see something like:

    Verification succeeded for <image>@sha256:...
    
  4. If verification still fails, inspect the image manifest:

    crane manifest harbor-wlye1f2u.lab.practical-devsecops.training/library/django.nv:1.0 | jq .
    

    Look for an annotations block containing org.opencontainers.image.signatures. If it’s missing, the sign step didn’t complete.

  5. Check Rekor (optional):

    cosign verify --rekor-url https://rekor.sigstore.dev \
        --key cosign.pub \
        harbor-wlye1f2u.lab.practical-devsecops.training/library/django.nv:1.0
    

3.4 Quick troubleshooting checklist

  • ✅ Signed the exact same image reference you are verifying.
  • ✅ Public key (cosign.pub) matches the private key used for signing.
  • ✅ Network access to the Rekor server (or use --skip-verify).
  • ✅ Image registry supports OCI signatures (most modern registries do).

Common Questions & Tips

Question Answer
Do I need to rebuild the image after adding a seccomp profile? No. The profile is attached at container‑run time via --security-opt. Rebuilding isn’t required.
Can Dockle be run against a Dockerfile directly? Dockle works on built images. Use docker build -t test . && dockle test or a CI step that builds then scans.
Is it safe to use --skip-verify with Cosign? Only for local testing. In production you should verify signatures and, optionally, the Rekor log.
Why does chmod sometimes work even when blocked? If you are the owner of the file, the kernel may allow the operation before seccomp checks. Blocking chmod on files you don’t own is the typical security posture.
How can I see which syscalls are currently allowed in a container? Run docker run --rm --security-opt seccomp=unconfined alpine:latest strace -c -e trace=%process -p 1 (replace PID as needed).

Bottom Line

  • Seccomp: Validate JSON syntax, architecture, and container launch flags; test each syscall individually.
  • Dockerfile security: Look for root usage, missing health checks, unpinned dependencies, and improper permissions; fix them before scanning with Dockle.
  • Cosign: Ensure the image is signed with the correct key, use the exact image reference, and confirm Rekor connectivity.

Follow this guide, and you’ll troubleshoot the most common lab roadblocks with confidence. Happy securing!