From threat-model
Analyze a PR for TNA (Two-Node Arbiter) security threats with STRIDE/DFD analysis, MITRE ATT&CK and OWASP mapping
How this skill is triggered — by the user, by Claude, or both
Slash command
/threat-model:tna-threat-modelThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Analyze a pull request for security threats against the **TNA (Two-Node Arbiter)** topology, map to MITRE ATT&CK, and generate a formal report.
Analyze a pull request for security threats against the TNA (Two-Node Arbiter) topology, map to MITRE ATT&CK, and generate a formal report.
This skill focuses on TNA-specific DFD elements, trust boundaries, and code paths. For TNF analysis, use /threat-model:tnf.
Bundled with this skill:
dfd-elements-tna.md — TNA DFD element catalog (TNA-P1, TNA-P3–P5, TNA-DS5–DS6, TNA-TB1–TB3)Shared references (in ../../references/):
mitre-reference.md — MITRE ATT&CK lookup with DFD element mappingsowasp-reference.md — OWASP Top 10:2025 mapping with DFD element cross-referencesmitre-findings-template.md — Template for cumulative findings trackerDiscovered at runtime from the workspace:
$THREAT_MODEL_DIR/TNA-THREAT-MODEL.md — TNA formal threat model with DFD and per-element STRIDE analysis$FINDINGS_FILE — TNA findings tracker (created from template on first use)Before starting analysis, discover the workspace layout.
Find workspace root: Walk upward from $PWD until a directory containing repos/ is found. If no parent qualifies, fall back to checking whether the current git repo sits inside a repos/ directory:
d="$PWD"
while [ "$d" != "/" ]; do
if [ -d "$d/repos" ]; then
echo "$d"
break
fi
d="$(dirname "$d")"
done
if [ "$d" = "/" ]; then
repo_root="$(git rev-parse --show-toplevel 2>/dev/null || true)"
if [ -n "$repo_root" ] && [ "$(basename "$(dirname "$repo_root")")" = "repos" ]; then
echo "$(dirname "$(dirname "$repo_root")")"
fi
fi
Set workspace paths: Once the workspace root (WORKSPACE) is found:
$WORKSPACE/repos/TNA-THREAT-MODEL.md in:
$WORKSPACE/repos/two-node-toolbox/docs/$WORKSPACE/docs/$WORKSPACE/reports/ (create if needed).$WORKSPACE/.claude/skills/threat-model/mitre-findings-tna.md — initialized from ../../references/mitre-findings-template.md on first use.Validate workspace: Warn the user if:
repos/ directory is found| Variable | Description | Example |
|---|---|---|
$WORKSPACE | Root directory containing repos/ | /home/user/Projects/tna-dev-env |
$REPOS | Repos directory | $WORKSPACE/repos |
$THREAT_MODEL_DIR | Directory containing formal threat model | $REPOS/two-node-toolbox/docs |
$REPORT_DIR | Directory for generated reports | Same as $THREAT_MODEL_DIR or $WORKSPACE/reports |
$FINDINGS_FILE | TNA findings tracker | $WORKSPACE/.claude/skills/threat-model/mitre-findings-tna.md |
Each threat-model skill writes to its own findings file (mitre-findings-tnf.md, mitre-findings-tna.md, mitre-findings-sno.md, mitre-findings-lvms.md), so no file locking is required during concurrent execution.
Append protocol (use in step 12):
FINDINGS_FILE="$WORKSPACE/.claude/skills/threat-model/mitre-findings-tna.md"
mkdir -p "$(dirname "$FINDINGS_FILE")"
cp -n "RESOLVED_TEMPLATE_PATH" "$FINDINGS_FILE"
cat >> "$FINDINGS_FILE" <<'FINDINGS_BLOCK'
## TNA — REPO PR #NUMBER (YYYY-MM-DD)
| Technique ID | Technique Name | Finding | Severity | Status | Notes |
|--------------|----------------|---------|----------|--------|-------|
| T#### | Name | VULN-# | Severity | Open | Description |
---
FINDINGS_BLOCK
Substitute RESOLVED_TEMPLATE_PATH with the absolute path to ../../references/mitre-findings-template.md (resolved from this skill's directory). Fill in REPO, NUMBER, YYYY-MM-DD, and the table rows from the current analysis.
/threat-model:tna 1437
Detects the repository from the current working directory. Must be inside a repo under $REPOS/<repo>/.
/threat-model:tna https://github.com/openshift/cluster-etcd-operator/pull/1437
Extracts org, repo, and PR number from the URL automatically.
/threat-model:tna cluster-etcd-operator 1437
Specify repo name and PR number explicitly.
If input is a URL (contains github.com):
https://github.com/<org>/<repo>/pull/<PR>If input is a single number:
repos/<repo-name>/ in the working directoryIf input is <repo> <number>:
| Repo | GitHub Org |
|---|---|
| assisted-service | openshift |
| cluster-etcd-operator | openshift |
| machine-config-operator | openshift |
| installer | openshift |
| cluster-baremetal-operator | openshift |
| origin | openshift |
| dev-scripts | openshift-metal3 |
| release | openshift |
| enhancements | openshift |
| openshift-docs | openshift |
gh pr view <PR> --repo <org>/<repo> or WebFetchgh pr diff <PR> --repo <org>/<repo> or WebFetchdfd-elements-tna.md$THREAT_MODEL_DIR/TNA-THREAT-MODEL.md (if found)../../references/mitre-reference.md)$REPORT_DIR/$FINDINGS_FILEShellCheck is available in RHEL/Fedora repos (dnf install ShellCheck) - no external downloads required.
command -v shellcheck >/dev/null && echo "shellcheck: installed" || echo "shellcheck: NOT installed (run: dnf install ShellCheck)"
shellcheck -f json <script-file>
shellcheck -S warning <script-file>
shellcheck -s bash <script-file>
| Code | Severity | Security Relevance | MITRE |
|---|---|---|---|
| SC2086 | Warning | Unquoted variable - command injection risk | T1059 |
| SC2091 | Warning | Command in $() used as condition - injection | T1059 |
| SC2046 | Warning | Unquoted command substitution | T1059 |
| SC2012 | Info | Parsing ls output - can be exploited | T1059 |
| SC2029 | Warning | ssh command with unescaped variables | T1059 |
| SC2087 | Warning | Unquoted heredoc - variable expansion | T1059 |
| SC2155 | Warning | Declare/assign separately to avoid masking errors | - |
| SC2164 | Warning | cd without without error-exit guard - path traversal risk | T1083 |
Add ShellCheck results under Automated Scanner Results:
## Automated Scanner Results
### ShellCheck
**Tool**: ShellCheck (from RHEL repos)
**Version**: X.X.X
| Code | Severity | File | Line | Message |
|------|----------|------|------|---------|
| SC2086 | warning | script.sh | 42 | Double quote to prevent globbing and word splitting |
If ShellCheck is not installed, note: Not installed. Install with: dnf install ShellCheck
If no shell scripts in PR, note: No shell scripts in this PR - skipped.
The following scanners provide additional coverage but require external downloads. Use at your own discretion.
| Tool | Source | Risks | Mitigations |
|---|---|---|---|
| Semgrep | pip/GitHub | Fetches rules from semgrep.dev; may send telemetry | Use --offline mode with local rules |
| Gitleaks | GitHub releases | Binary from external source | Verify checksums; use container image |
| gosec | GitHub/go install | Binary from external source | Verify checksums; audit source |
command -v semgrep >/dev/null && echo "semgrep: installed" || echo "semgrep: not installed (external)"
command -v gitleaks >/dev/null && echo "gitleaks: installed" || echo "gitleaks: not installed (external)"
command -v gosec >/dev/null && echo "gosec: installed" || echo "gosec: not installed (external)"
| Category | Patterns | MITRE | Severity |
|---|---|---|---|
| Command Injection | shell exec, os.system, subprocess, fmt.Sprintf with shell | T1059 | Critical |
| Credentials | hardcoded secrets, API keys, tokens, passwords in code | T1552 | Critical |
| Privilege Escalation | setuid, capabilities, privileged containers, sudo, nsenter | T1548 | High |
| Authentication | auth bypass, weak validation, token handling flaws | T1078 | High |
| Crypto Weakness | weak algorithms, hardcoded keys, disabled TLS verify | T1573 | High |
| Path Traversal | unsanitized file paths, symlink attacks | T1083 | Medium |
| Container Escape | host mounts, hostPID, hostNetwork, privileged mode | T1611 | Critical |
| Logging Exposure | sensitive data in logs, credential printing | T1005 | Medium |
| SSRF/Network | unvalidated URLs, exposed internal endpoints | T1046 | Medium |
| Deserialization | unsafe unmarshal, pickle, yaml.load | T1059 | High |
See dfd-elements-tna.md for the full element catalog.
| Code Path Pattern | DFD Element | STRIDE Focus |
|---|---|---|
installer/pkg/asset/machines/arbiter* | TNA-P1 (Installer) | T, D |
installer/pkg/asset/ignition/machine/arbiter* | TNA-P1, TNA-DS6 | T, I |
installer/pkg/types/installconfig.go (IsArbiterEnabled) | TNA-P1 | T, D |
installer/pkg/types/validation/installconfig.go (arbiter) | TNA-P1 | T |
assisted-service/internal/common/common.go (arbiter) | TNA-P1 | T |
assisted-service/internal/cluster/validator.go (arbiter role) | TNA-P1 | S, T |
machine-config-operator/manifests/arbiter* | TNA-P3 (MCO) | T, D |
machine-config-operator/templates/arbiter/ | TNA-P3 | T, E |
cluster-etcd-operator/pkg/operator/ceohelpers/control_plane_topology.go | TNA-P4 (CEO) | T, D |
cluster-etcd-operator/pkg/operator/ceohelpers/multiselector_lister.go | TNA-P4 | T, D |
cluster-etcd-operator/pkg/operator/configobservation/*replicas* | TNA-P4 | T, D |
origin/test/extended/two_node/arbiter_topology.go | Test | - |
origin/test/extended/two_node/tna_recovery.go | Test | - |
When a PR modifies code that crosses a trust boundary, apply additional scrutiny:
| Boundary Crossing | Code Indicators | Key Threats |
|---|---|---|
| TNA-TB1->TNA-TB2 (Admin -> K8s API) | install-config, oc commands | S (admin impersonation), T (config tampering) |
| TNA-TB2 internal (MCO -> kubelet) | arbiter MCP, kubelet config, taint | T (taint removal), D (misconfiguration) |
| TNA-TB2->TNA-TB3 (K8s API -> Worker) | CSR approval, ignition endpoint | S (rogue CSR), E (lateral movement) |
For each affected DFD element, ask these questions:
Processes (all 6 STRIDE categories):
Data Stores (T, I, D):
Data Flows (T, I, D):
External Entities (S, R):
After identifying per-element threats, check against $THREAT_MODEL_DIR/TNA-THREAT-MODEL.md:
PE-<element>-* IDs in the Per-Element STRIDE Analysis sectionIf the formal threat model file is not found, skip cross-referencing and note this in the report.
PR<number>-THREAT-MODEL-<repo>.mdVULN-PR<number>-<short-desc>.md# PR #<number> Threat Analysis: <PR Title>
**Document Version**: 1.0
**Date**: YYYY-MM-DD
**Classification**: Internal - Security Sensitive
**Repository**: <repo>
**Topology**: TNA
**PR Author**: <author>
**PR URL**: <url>
---
## Executive Summary
[Brief overview of the PR and key security findings]
### Findings Summary
| Severity | Count | Summary |
|----------|-------|---------|
| Critical | X | [brief] |
| High | X | [brief] |
| Medium | X | [brief] |
| Low | X | [brief] |
---
## Change Overview
[What this PR does, its purpose, and security-relevant changes]
---
## Affected Files
| File | Changes | Security Relevance |
|------|---------|-------------------|
| path/to/file.go | +X/-Y lines | [relevance] |
---
## DFD Impact Analysis
This PR affects the following elements in the TNA Data Flow Diagram
(see TNA-THREAT-MODEL.md):
### Affected DFD Elements
| Element | Name | Impact | Trust Boundary |
|---------|------|--------|----------------|
| P# | [process name] | [what changed] | TB# |
| DS# | [store name] | [what changed] | TB# |
| DF# | [flow description] | [what changed] | TB#->TB# |
### Trust Boundary Crossings
[Describe any trust boundaries crossed by the changed code]
### Per-Element STRIDE
| Element | S | T | R | I | D | E | Notes |
|---------|---|---|---|---|---|---|-------|
| P# | - | - | - | - | - | - | [Processes: all 6] |
| DS# | N/A | - | N/A | - | - | N/A | [Data Stores: T, I, D] |
| DF# | N/A | - | N/A | - | - | N/A | [Data Flows: T, I, D] |
| EE# | - | N/A | - | N/A | N/A | N/A | [External Entities: S, R] |
**Legend**: **X** = new threat found, **~** = existing threat modified, **-** = no impact, N/A = not applicable
### Threat Model Cross-Reference
| PR Finding | Existing PE-* ID | Status |
|------------|-----------------|--------|
| [finding] | PE-XX-X-X | Matches existing / New gap / Mitigated |
---
## Threat Analysis
### VULN-1: [Vulnerability Title]
**Severity**: Critical/High/Medium/Low
**OWASP**: A##:2025 - Category Name
**MITRE ATT&CK**: T#### - Technique Name
**CWE**: CWE-###
#### Affected Code
**File**: `path/to/file.go:line`
#### Description
[Detailed description of the vulnerability]
#### Attack Vector
[How this could be exploited]
#### Impact
- **Confidentiality**: [impact]
- **Integrity**: [impact]
- **Availability**: [impact]
#### Recommended Fix
[Code showing the fix]
---
## OWASP & MITRE ATT&CK Mapping
| Finding | OWASP | MITRE | CWE | Status |
|---------|-------|-------|-----|--------|
| VULN-1 | A05:2025 Injection | T1059 | CWE-78 | Open |
---
## Risk Assessment
| Finding | Likelihood | Impact | Risk |
|---------|------------|--------|------|
| VULN-1 | High | Critical | Critical |
---
## Recommendations
### For Developers (Code Changes)
#### Before Merge
1. [Code fix or change required in this PR]
#### After Merge
1. [Follow-up code improvement, test addition, or refactor]
### For Customers (Deployment & Operations)
#### Configuration Hardening
1. [Cluster configuration or hardening recommendation]
#### Operational Practices
1. [Monitoring, incident response, or day-2 operational guidance]
---
## References
- [OWASP Top 10:2025](https://owasp.org/Top10/2025/)
- [MITRE ATT&CK](https://attack.mitre.org/)
- [Relevant CVEs, CWEs, documentation]
# Security Ticket: [Vulnerability Title]
**Ticket ID**: VULN-PR<number>-<seq>
**Severity**: CRITICAL/HIGH
**Component**: <repo>
**Status**: Open
**Created**: YYYY-MM-DD
**PR**: #<number>
## Summary
[One paragraph summary]
## Affected Code
**File**: `path/to/file.go:lines`
## Exploitation
### Attack Flow
[ASCII diagram or description of attack flow]
### Exploit Examples
[Code examples showing exploitation]
## Impact
[Detailed impact analysis]
## Recommended Fix
### For Developers
[Code showing the fix with explanation]
### For Customers
[Deployment hardening, configuration changes, or monitoring guidance]
## References
- [CWE, OWASP, other references]
These are the repos expected in $REPOS/:
| Repo | Org | Focus Areas |
|---|---|---|
| assisted-service | openshift | API security, credential handling |
| cluster-etcd-operator | openshift | Topology detection, etcd config |
| machine-config-operator | openshift | Arbiter MCP, node config |
| installer | openshift | Arbiter install config, ignition |
| origin | openshift | Test code security |
| dev-scripts | openshift-metal3 | Shell scripts, credential handling |
Provides CDSS development patterns for drug interaction checking, dose validation, clinical scoring (NEWS2, qSOFA), and alert classification integrated into EMR workflows.
npx claudepluginhub openshift-eng/edge-tooling --plugin threat-model