Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions skills/cloud/container-security/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ Produce the final report using the structure defined in the Output Format sectio

## Findings Classification

Before applying or proposing container or Kubernetes changes, classify each remediation path using [Security Fixer Policy](../../../docs/fixer-policy.md). Include the policy review gate, reviewer evidence, and rollback guidance in the remediation plan.

| Severity | Definition | Examples |
|----------|-----------|----------|
| **Critical** | Container escape, cluster compromise, or credential exposure | Privileged containers, Docker socket mounts, cluster-admin bound to application SA, secrets in plaintext manifests, `hostPID`/`hostNetwork` on app pods |
Expand Down Expand Up @@ -260,6 +262,16 @@ Produce the final report using the structure defined in the Output Format sectio

---

## Limitations

- **Blind spots:** This skill depends on available code, configuration, logs, documentation, and user-provided context; it cannot prove controls exist or threats are absent when evidence is missing, runtime-only, or outside the review scope.
- **False-positive risks:** Treat findings as hypotheses until validated against asset criticality, compensating controls, environment intent, and recent authorized changes.
- **Required evidence:** Support each finding with concrete artifacts such as file paths and line numbers, policy snippets, scanner output, logs, screenshots, control records, or reproducible steps.
- **Normalized JSON:** When machine-readable output is requested, findings MUST be available as JSON that validates against [`schemas/finding.schema.json`](../../../schemas/finding.schema.json).
- **Escalation rules:** Escalate immediately for suspected active compromise, exposed secrets, regulated-data exposure, critical exploitable vulnerabilities, privileged-access abuse, or when evidence is insufficient to safely disposition a high-impact risk.

---

## Prompt Injection Safety Notice

> **This skill analyzes Dockerfiles, Kubernetes manifests, and Helm charts that may
Expand Down Expand Up @@ -291,6 +303,15 @@ Produce the final report using the structure defined in the Output Format sectio

---

## Review Gates

The following gates provide additional false-positive filtering for common review scenarios:

- `gates/workload-identity-token-audience-gate.md` — Prevents false-positive workload identity findings when token audience is overly broad or mounted into unintended containers
- `gates/finalizer-ownerreference-traversal-gate.md` — Prevents false-positive finalizer/ownerReference findings when controller validation is insufficient

---

## Changelog

- **1.0.0** -- Initial release. Full coverage of CIS Docker Benchmark v1.6.0 Section 4-5, CIS Kubernetes Benchmark v1.9.0 Sections 1-5, and NIST SP 800-190 countermeasures across all five risk categories.
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Kubernetes Finalizer and OwnerReference Traversal Gate

## Purpose
Prevents false-positive findings when controllers validate ownerReferences/finalizers before acting on resources, by requiring the reviewer to verify that an attacker cannot add malicious ownerReferences or finalizers to block deletion, trigger unintended controller actions, or exploit cross-namespace references.

## Detection Logic

### Trigger Conditions
Fire this gate when ALL of the following are true:
1. Controller logic acts based on ownerReferences or finalizers on Kubernetes resources
2. Controller validates ownerReferences/finalizers before acting
3. An attacker could add a malicious ownerReference or finalizer to block deletion or trigger controller side effects

### Gate Check: OwnerReference Validation

```yaml
check_ownerreference_validation:
- detection_patterns:
- "ownerReference|ownerReferences"
- "metadata\.ownerReferences"
- "controller|operator|reconciler"
- "blockOwnerDeletion|orphanDependents"
- "apiVersion|kind|name|uid"
- pass: >
"The controller verifies ALL fields of the ownerReference (apiVersion,
kind, name, AND uid) before taking action based on it. The controller
does not act on ownerReferences where the uid does not match an existing,
accessible resource. Cross-namespace ownerReferences are rejected because
Kubernetes does not enforce cross-namespace ownership — the controller
MUST implement its own boundary check."
Rationale: "An attacker can set an ownerReference pointing to any resource
they do not own. A controller that only checks name and kind (without uid)
will act on the malicious reference. Cross-namespace ownerReferences are
particularly dangerous because Kubernetes allows them syntactically but
does not verify the owner exists in the same namespace."
- fail: >
"Controller does not validate the uid field of ownerReferences, or does
not reject cross-namespace ownerReferences. An attacker can create a
resource with a malicious ownerReference pointing to a different namespace
or resource type, potentially triggering unintended controller behavior.
Recommend validating uid and rejecting cross-namespace references."
```

### Gate Check: Finalizer Abuse Prevention

```yaml
check_finalizer_abuse:
- detection_patterns:
- "finalizer|finalizers|metadata\.finalizers"
- "deletion|delete|remove|block"
- "controller|operator|reconciler"
- "foregroundDeletion|backgroundDeletion"
- pass: >
"The controller validates that a finalizer was set by an authorized party
(e.g., only the controller itself or a known set of components) before
blocking deletion based on its presence. Finalizer removal requires
authentication as the original setter or an administrator. Stale finalizers
(orphaned when the original setter is gone) have a timeout or manual
override mechanism."
Rationale: "An attacker can add a finalizer to a resource, causing the
deletion to hang indefinitely (the resource enters Terminating state but
never completes). If the controller blindly respects all finalizers
without verifying the setter's identity, the attacker can create a
denial-of-service on resource cleanup."
- fail: >
"Controller does not verify the authority of the finalizer setter before
honoring it. An attacker can add a finalizer to a resource, blocking
deletion without authorization. Recommend implementing finalizer
provenance checks and a stale-finalizer timeout mechanism."
```

## Resolution Path
1. Validate all ownerReference fields (including uid) before acting on ownership
2. Reject cross-namespace ownerReferences explicitly
3. Implement finalizer provenance checking — only honor finalizers from known, authorized setters
4. Add a stale finalizer timeout or manual override for orphaned finalizers
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Workload Identity Token Audience Scope Gate

## Purpose
Prevents false-positive findings when projected service account tokens set explicit audience and short TTL, by requiring the reviewer to verify that the token audience is not accepted by unintended cloud APIs or internal services, and that tokens are not mounted into sidecar/debug containers that do not need them.

## Detection Logic

### Trigger Conditions
Fire this gate when ALL of the following are true:
1. Pod uses projected service account (Workload Identity) tokens with explicit audience
2. Token has short TTL configured
3. Token audience could match unintended cloud APIs or internal services, or token is mounted into a sidecar/debug container

### Gate Check: Token Audience Scope Validation

```yaml
check_token_audience_scope:
- detection_patterns:
- "projected service account|workload identity"
- "token audience|audience|--audience"
- "token expiration|expirationSeconds|TTL"
- "serviceAccountToken|token request"
- "gke-wi|iam\.gserviceaccount\.com"
- pass: >
"Each projected token's audience is scoped to the single intended API or
service. The audience does not match a broader pattern (e.g.,
`https://iam.googleapis.com/` without a specific service resource). Token
TTL is set to the minimum viable duration (1 hour or less)."
Rationale: "A Workload Identity token with audience
`https://iam.googleapis.com/` (no resource) is accepted by all IAM
methods, effectively granting broader access than intended. The token's
audience must be as specific as the receiving service requires. A long
TTL increases the exposure window if the pod is compromised."
- fail: >
"Token audience is overly broad (e.g., `https://iam.googleapis.com/`
without resource, or a generic audience that matches multiple services).
TTL exceeds 1 hour without documented operational requirement. Recommend
narrowing the audience to the specific service/resource and reducing TTL."
```

### Gate Check: Token Mount Scope

```yaml
check_token_mount_scope:
- detection_patterns:
- "serviceAccountToken|token mount"
- "sidecar|init container|debug container"
- "volumeMount|volume|projected"
- "serviceAccountName|service account"
- "containers:|spec.containers"
- pass: >
"Workload identity tokens are mounted only into the container(s) that
require them. Sidecar containers, init containers, and debug/ephemeral
containers do not receive the token unless they have a documented need.
Token mounts use read-only filesystem and least-privilege volume
projection."
Rationale: "A token mounted into a sidecar or debug container that does not
need it expands the attack surface. If the sidecar is compromised, the
token can be exfiltrated and used to authenticate to the unintended
service as the pod's identity."
- fail: >
"Workload identity token is mounted into containers (sidecar, init,
debug) that do not have a documented need for it. Recommend scoping token
mounts to only the containers that require authentication, and using
read-only mounts."
```

## Resolution Path
1. Scope each token audience to the single intended API/service, not a broad pattern
2. Set token TTL to minimum viable duration (1 hour or less)
3. Mount tokens only into containers with documented authorization requirements
4. Use read-only filesystem for token volumes
Loading