docs(security): expand supply chain defense guide with deep research findings

Co-authored-by: Junie <junie@jetbrains.com>
This commit is contained in:
ja
2026-03-23 23:16:34 +01:00
co-authored by Junie
parent 519142f0d7
commit 8670ecd787
+730
View File
@@ -0,0 +1,730 @@
---
description: >-
Supply chain security assessment and comprehensive defense guide for
March 2026 incidents (Trivy/TeamPCP, CanisterWorm, GlassWorm).
tags: [security, supply-chain, incident-response, hardening, defense-guide]
last_updated: '2026-03-23'
priority: 10
---
# Supply Chain Security Assessment (March 2026)
## Scan Results
| Check | Status | Detail |
|-------|--------|--------|
| CanisterWorm persistence | **CLEAN** | No `pgmon` service, no `~/.local/share/pgmon/` |
| TeamPCP C2 connection | **CLEAN** | No active connection to `45.148.10.212` |
| TeamPCP exfil repos | **CLEAN** | No `tpcp-docs-*` repos found |
| ICP C2 connection | **CLEAN** | No active connection to ICP endpoint |
| DNS resolution (C2) | **NOTES** | `scan.aquasecurtiy.org` still resolves to `45.148.10.212` (not yet sinkholed) |
| DNS resolution (ICP) | **NOTES** | ICP endpoint resolves via Dfinity boundary nodes (expected - decentralized) |
### Note on DNS Resolution
C2 domains resolving is expected - they have not been fully sinkholed. The critical check is **active connections**, which are absent.
## Threat Landscape Summary
### Trivy/TeamPCP (March 19-22)
- Tag poisoning on `aquasecurity/trivy-action` (75 tags)
- Memory-based credential theft via `/proc/<pid>/mem`
- Exfiltration via typo-squatted domain + victim's own GitHub repos
- Safe version: `aquasec/trivy:0.69.3@sha256:0d52a20836526e387157a55f9368d4001c95b77c3855a9010049448106a6b5e0`
### CanisterWorm (March 20)
- 66+ malicious npm packages via stolen tokens
- Self-propagating: harvests npm tokens, republishes victim's packages
- Persistence: systemd user service (`pgmon`)
- C2: ICP blockchain (resistant to takedown)
- Preceded by "Shai Hulud" worm (2025) - now a recurring pattern
- Related 2026 campaigns: Shai-Hulud 2.0 (preinstall phase, destructive fallback), SANDWORM_MODE (MCP injection, multi-channel exfil)
### GlassWorm (January-March 2026)
- Invisible Unicode chars (U+FE00-FE0F, U+E0100-E01EF) encode payloads
- 151+ GitHub repos, 72+ VS Code/Open VSX extensions, 400+ total affected packages
- Commits blend in with realistic surrounding changes (AI-generated)
- **Cannot be detected by visual code review or standard linting**
- Decoder pattern: maps codepoints to byte values, passes to `eval(Buffer.from(...))`
---
## Defense Technologies (Deep Research Findings)
### Layered Detection Architecture
```text
Layer 1 (Preventive): Workflow Policy + SHA Pinning + OIDC
Layer 2 (Preventive): npm Hardening + Token Scoping + Script Sandboxing
Layer 3 (Detective): Runtime Monitoring (eBPF: Falco/Tetragon/Tracee)
Layer 4 (Detective): Unicode Scanning + Pre-commit Hooks
Layer 5 (Detective): SBOM + Vuln Scanning (syft/grype) + Nuclei
Layer 6 (Detective): DNS/Network Monitoring + Threat Intel Feeds
Layer 7 (Response): Credential Rotation + Incident Playbook
```
### 1. GitHub Actions Hardening (Trivy/TeamPCP Defense)
#### SHA256 Digest Pinning
All Actions MUST be pinned to full commit SHA, never tags or branches:
```yaml
# WRONG - vulnerable to tag poisoning
- uses: aquasecurity/trivy-action@0.69.3
# CORRECT - immutable
- uses: aquasecurity/trivy-action@a12a3943b4151b629d348435e26e7cb35bc0db20
```
#### OIDC Token Hardening
- Enforce short-lived tokens (5-15 min expiration)
- Restrict token audience to specific cloud providers and repositories
- Use conditional access policies tied to repository, branch, and environment
- Disable all long-lived PATs; enforce OIDC for machine accounts
#### Environment Protection Rules
```yaml
environments:
production:
protection_rules:
- type: required_reviewers
reviewers: 2
- type: wait_timer
minutes: 30
- type: restrict_to_deployment_keys
```
#### Reusable Workflow Security
- Store in private repos with explicit access controls
- Require signed commits for workflow updates
- Pin calls to specific commits, not branches
- Audit log all workflow invocations
#### Action Allowlist Enforcement
```yaml
# Branch protection or custom CI check
approved_actions:
- actions/checkout@a1b2c3d4e5f6
- actions/setup-node@f1b2c3d4e5f6
- org/internal-action@abcdef123456
enforcement: reject_if_not_in_list
```
#### Tag Poisoning Detection
Verify action repos for suspicious signals:
- Tag has been force-pushed (multiple SHAs for same tag)
- Repo created < 90 days ago
- Zero stars and zero forks
- Unknown or compromised maintainers
Tools: Snyk GitHub Actions Security (auto-scans workflows), SLSA provenance verification.
### 2. Memory Forensics (TeamPCP `/proc/pid/mem` Defense)
#### Attack Vector
`/proc/[pid]/mem` access allows reading running process memory to extract credentials, tokens, and secrets. TeamPCP targets CI/CD runners holding temporary credentials during workflow execution.
#### Detection Techniques
**Volatility 3** - Post-incident memory analysis:
```bash
vol3 -f memory.dump linux.psaux # Process list with env vars
vol3 -f memory.dump linux.bash # Command history
# Scan for credential patterns: ghp_*, ghu_*, AWS_*, npm_*
```
**eBPF Real-Time Monitoring** - Detect access at syscall level:
```c
// Trace openat syscall for /proc/*/mem access
TRACEPOINT_PROBE(syscalls, sys_enter_openat) {
char path[256];
bpf_probe_read_user_str(&path, sizeof(path), (void *)ctx->args[1]);
if (strstr(&path, "/proc") && strstr(&path, "mem")) {
events.perf_submit(ctx, &event, sizeof(event));
}
return 0;
}
```
**memdump** - Capture CI/CD runner memory post-execution, scan for credential remnants before process termination.
#### Defensive Countermeasures
```yaml
# Container runtime - deny ptrace capability
securityContext:
capabilities:
drop: [SYS_PTRACE]
readOnlyRootFilesystem: true
```
- Deploy runners in VM isolation (not container-only)
- Enable hardware memory encryption (Intel TME / AMD SEV-SNP)
- Rotate all credentials immediately post-workflow execution
### 3. eBPF Runtime Security (Cross-Vector Detection)
#### Tool Comparison
| Tool | Strength | Best For | Enforcement |
|------|----------|----------|-------------|
| **Falco** | Rules-based alerting | Container environments, broad adoption | Alert only (SIGSTOP可选) |
| **Tetragon** | Kubernetes-native, policy enforcement | K8s clusters, tracing policies | Kill/block via policy |
| **Tracee** | Deep syscall tracing, eBPF-only | Bare-metal, CI/CD runners | Alert + filter |
#### Falco Rules for Supply Chain Attacks
```yaml
- rule: Unauthorized Process Memory Access
condition: >
open and container and
fd.name glob "/proc/*/mem" or syscall == ptrace
output: "Unauthorized memory access (user=%user.name cmd=%proc.name file=%fd.name)"
priority: CRITICAL
tags: [supply-chain, memory_access]
- rule: Suspicious Env Variable Exfiltration
condition: >
syscall == execve and container and
proc.name in (curl, wget, nc, python) and
(proc.args contains "GITHUB_TOKEN" or proc.args contains "ghp_" or proc.args contains "npm_")
priority: CRITICAL
tags: [supply-chain, credential_exfil]
- rule: Suspicious Systemd Service Creation
condition: >
open_write and fd.name glob "*/.config/systemd/user/*" and
not proc.name in (systemctl, systemd, ansible)
priority: HIGH
tags: [supply-chain, persistence]
```
#### Tetragon TracingPolicy (Enforcement)
```yaml
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
name: block-proc-mem-access
spec:
kprobes:
- call: "__fput"
selectors:
- matchArgs:
- index: 0
operator: "Equal"
values: ["/proc/*/mem"]
action: SIGKILL
```
#### Tracee for CI/CD Runner Monitoring
```bash
tracee \
--events=open,openat,ptrace,execve \
--filter='container and (event.args.pathname contains "/proc" and event.args.pathname contains "mem")' \
--output json \
--output-file events.json
```
**Workstation Note**: eBPF tools require kernel support. For this Arch Linux workstation, `bpf` package provides headers. Falco can run in agent mode for local monitoring.
### 4. npm Supply Chain Defense (CanisterWorm Defense)
#### Lifecycle Script Mitigation
```bash
# Global disable (already applied)
npm config set ignore-scripts true
# Per-project override when needed
npm ci --ignore-scripts=false --only=dev # explicit opt-in
# Node.js policy-based sandboxing (experimental)
node --experimental-policy=policy.json install
```
**Limitation**: Shai-Hulud 2.0 uses **preinstall** phase, bypassing postinstall-focused defenses. `--ignore-scripts` blocks both, but some legitimate packages require scripts. Use allowlists:
```json
// policy.json - allow specific packages only
{
"resources": {
"node_modules/.package-lock.json": {
"integrity": true
}
},
"dependencies": {
"package:lodash": true,
"package:express": true
}
}
```
#### Token Security
| Practice | Implementation |
|----------|---------------|
| Granular Access Tokens (GAT) | Scope to specific repos + read-only or automation permissions |
| Token expiration | Set max 90 days; automate rotation |
| Never store in `.npmrc` | Use environment variables or OIDC |
| Audit tokens quarterly | `npm token list`, revoke unused |
| MFA enforcement | Required for package publish (prevents bypass token abuse) |
#### npm OIDC (Long-Term Fix)
npm OIDC integration is "very hard to compromise" and would "almost completely erase supply-chain attack surface" (Chainguard, 2026). Enables tokenless authentication for package operations.
#### Systemd Service Monitoring (CanisterWorm `pgmon`)
```bash
# Detect unknown user services
systemctl --user list-units --type=service --all
# Audit service files for anomalies
ls -la ~/.config/systemd/user/
# Check for services with suspicious exec paths
grep -r "ExecStart" ~/.config/systemd/user/ | grep -v "/usr/bin\|/usr/local/bin"
# Monitor service file creation (eBPF Falco rule above)
```
#### ICP Blockchain C2 Detection
- Decentralized C2 via ICP canisters is resistant to traditional takedown
- Monitor for outbound connections to Dfinity boundary nodes from unexpected processes
- Network baseline: CI/CD runners should never connect to ICP endpoints
- Block ICP boundary node IPs at firewall level for non-ICP workloads
#### Worm Containment
- **socket.dev**: Detects malicious packages within 2-5 minutes of publication via differential analysis
- Monitor all npm packages under org control for unauthorized version publishes
- Alert on rapid-succession version publishes (1-3 day windows = suspicious)
- Revoke and rotate tokens immediately if compromise suspected
### 5. Unicode Attack Defense (GlassWorm Defense)
#### Understanding the Decoder Pattern
GlassWorm uses this exact decoder signature:
```javascript
const s = v => [...v].map(w => (
w = w.codePointAt(0),
w >= 0xFE00 && w <= 0xFE0F ? w - 0xFE00 :
w >= 0xE0100 && w <= 0xE01EF ? w - 0xE0100 + 16 : null
)).filter(n => n !== null);
eval(Buffer.from(s(``)).toString('utf-8'));
```
Detection must target: `eval()` + `Buffer.from()` + codepoint arithmetic + apparent empty/whitespace strings.
#### Detection Tools
```bash
# Variation Selectors (VS1-VS16)
grep -rP "[\x{FE00}-\x{FE0F}]" . --exclude-dir=node_modules --exclude-dir=.git
# Ideographic Variation Selectors
grep -rP "[\x{E0100}-\x{E01EF}]" . --exclude-dir=node_modules --exclude-dir=.git
# Combined with decoder pattern
grep -rP "(codePointAt|fromCharCode|Buffer\.from)" . \
--include="*.js" --include="*.ts" --exclude-dir=node_modules
```
Python scanner for byte-level detection:
```python
#!/usr/bin/env python3
"""Scan files for GlassWorm Unicode injection patterns."""
import sys, pathlib
VS_RANGES = [(0xFE00, 0xFE0F), (0xE0100, 0xE01EF)]
def scan_file(path):
content = path.read_bytes()
hits = []
for i, b in enumerate(content):
# Check for multi-byte UTF-8 sequences in VS ranges
if b >= 0xEF: # Start of 3-byte UTF-8 (VS range)
if i + 2 < len(content):
cp = int.from_bytes(content[i:i+3], 'big')
for start, end in VS_RANGES:
if start <= cp <= end:
hits.append((i, hex(cp)))
return hits
for p in pathlib.Path(sys.argv[1]).rglob('*'):
if p.suffix in ('.js', '.ts', '.mjs', '.cjs', '.py', '.json'):
hits = scan_file(p)
if hits:
print(f"{p}: {len(hits)} invisible chars found")
for offset, cp in hits[:5]:
print(f" offset {offset}: {cp}")
```
#### Git Pre-commit Hook
```yaml
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: no-invisible-unicode
name: Block invisible Unicode (GlassWorm defense)
entry: python3 scripts/unicode-scanner.py
language: script
types: [text]
```
#### IDE Visibility Configuration
**VS Code** - Show invisible characters:
```json
{
"editor.renderWhitespace": "all",
"editor.unicodeHighlight.ambiguousCharacters": true,
"editor.unicodeHighlight.invisibleCharacters": true
}
```
**Vim/Neovim**:
```vim
set list
set listchars+=trail:~,nbsp:␣
" Conceal off for PUA/VS ranges
syntax match GlassWorm "[\uFE00-\uFE0F\uE0100-\uE01EF]" cchar=
```
#### VS Code Extension Security
- Verify extension publisher identity before install
- Audit extension update history for suspicious version jumps
- Known malicious: `quartz.quartz-markdown-editor` v0.3.0 (March 12, 2026)
- 72+ malicious Open VSX extensions in coordinated campaign
- Prefer extensions with signed commits and provenance
- Review extension permissions (workspace access, terminal access = high risk)
#### Semgrep Rules
```yaml
rules:
- id: glassworm-decoder-pattern
patterns:
- pattern-either:
- pattern: |
eval(Buffer.from($FN(...)).toString(...))
- pattern: |
$VAR = $V => [...$V].map($W => ($W = $W.codePointAt(0), ...))
message: "Potential GlassWorm Unicode decoder pattern detected"
severity: ERROR
languages: [javascript, typescript]
```
### 6. SLSA Provenance & Sigstore Ecosystem
#### SLSA Framework (v1.2 Current)
| Level | Requirement | This Workstation |
|-------|-------------|-----------------|
| L1 | Documented build process | Partial (Ansible) |
| L2 | Hosted build platform | N/A (local dev) |
| L3 | Hardened build + provenance | N/A |
| L4 | Hermetic + reproducible | N/A |
**Applicability**: SLSA primarily targets CI/CD builds. For this local workstation, focus on L1 (documented process) and verifying SLSA provenance of consumed packages/artifacts.
#### Sigstore Components
| Component | Purpose | Tool |
|-----------|---------|------|
| **cosign** | Container image signing/verification | `pacman -S cosign` |
| **fulcio** | Certificate authority (issues certs based on OIDC) | Service |
| **rekor** | Transparency log (immutable record) | Service |
| **sigstore-js** | Node.js client library | `pnpm add @sigstore/sign` |
```bash
# Verify a container image was signed
cosign verify --certificate-identity=action@github.com \
--certificate-oidc-issuer=https://token.actions.githubusercontent.com \
aquasec/trivy:0.69.3
# Sign an artifact
cosign sign --key env://COSIGN_PRIVATE_KEY my-image:latest
```
#### in-toto Attestations
in-toto provides a framework for verifying the integrity of the software supply chain. Key concepts:
- **Layout**: Defines expected steps, authorized functionaries, and inspection rules
- **Attestation**: Metadata about a supply chain step (linked to SLSA provenance)
- **Verification**: Client-side check that all steps match the layout
Integration with GitHub Actions via `slsa-github-generator`:
```yaml
- uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.10.0
with:
attestation-name: my-attestation
```
### 7. SBOM Management
#### Toolchain
```bash
# Generate SBOM (CycloneDX format - preferred for security)
syft packages dir:./src -o cyclonedx-json > sbom.json
# Alternative: SPDX format (preferred for license compliance)
syft packages dir:./src -o spdx-json > sbom.spdx.json
# Scan SBOM for vulnerabilities
grype sbom:sbom.json --fail-on high
```
#### Format Choice
| Format | Best For | Tooling |
|--------|----------|---------|
| **CycloneDX** | Security scanning, vulnerability matching | grype, Dependency-Track |
| **SPDX** | License compliance, legal | SPDX tools, FOSSA |
#### Dependency-Track (SBOM Repository)
Centralized SBOM storage and continuous monitoring:
- Upload SBOMs via API on each build
- Continuous vulnerability scanning (NVD, OSV, GitHub Advisories)
- Policy evaluation (fail builds on critical vulns)
- This workstation: run via Docker for local SBOM management
### 8. Nuclei Template-Based Scanning
```bash
# Install
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
# Scan for known supply chain C2 indicators
nuclei -t supply-chain/ -u scan.aquasecurtiy.org
# Scan local git repos for TeamPCP exfil patterns
nuclei -t custom/teampcp-exfil.yaml -target https://github.com/org/repo
# Custom template for C2 domain detection
cat <<'EOF' > nuclei-teampcp.yaml
id: teampcp-c2-detection
info:
name: TeamPCP C2 Domain
severity: critical
dns:
- name: "{{Hostname}}"
matchers:
- type: word
words:
- "45.148.10.212"
EOF
```
### 9. ML-Based & Behavioral Detection (Emerging)
#### ML Detection Approaches for Supply Chain Attacks
| Technique | Application | Tools/Platforms |
|-----------|-------------|-----------------|
| **Package behavior modeling** | Detect anomalous postinstall behavior vs. historical baseline | socket.dev (differential analysis), EndorLabs |
| **Dependency graph anomaly detection** | Flag sudden dependency additions, version spikes, or transitive changes | Snyk Advisor, Socket.dev risk scores |
| **Code embedding similarity** | Detect AI-generated commits that mimic project style (GlassWorm evasion) | CodeQL ML models, GitHub Advanced Security |
| **Network behavior profiling** | Detect C2 beacon patterns, unusual outbound from build runners | Elastic ML, CrowdStrike Falcon |
| **File system entropy analysis** | Detect encoded payloads (Unicode steganography, encrypted strings) | YARA rules + ML classifiers |
#### Behavioral Detection Patterns
**Anomalous Package Behavior** (CanisterWorm/Shai-Hulud):
- Package executes network calls during install (baseline: most packages don't)
- Package writes files outside `node_modules` during install
- Package reads environment variables or `.npmrc` during install
- Package spawns child processes during install
- Detection: compare current package behavior against historical behavior profile
**Anomalous Commit Patterns** (GlassWorm):
- Commit modifies only whitespace/Unicode but diff shows zero visual changes
- Commit timestamp clusters with other suspicious commits across repos (coordinated campaign signal)
- Commit author style differs from project norm (AI-generated code detection)
- Detection: `git diff --word-diff` to catch invisible char changes; commit metadata clustering
**Anomalous Build Behavior** (TeamPCP):
- Build process accesses `/proc/*/mem` (never legitimate in CI)
- Build process resolves non-whitelisted DNS (tag poisoning C2 indicator)
- Build process creates outbound connections to non-cdn endpoints
- Detection: Falco rules (above), DNS query logging, network egress allowlists
#### Implementation for This Workstation
```bash
# Socket.dev CLI - local package risk scoring
npm install -g socket-cli
socket view express # Risk profile before installing
socket scan ./src # Scan dependencies for behavioral anomalies
# YARA rule for GlassWorm encoded payloads (high entropy strings)
# Install: pacman -S yara
cat <<'EOF' > rules/glassworm.yar
rule GlassWorm_Unicode_Payload {
strings:
$decoder = /codePointAt.*0xFE00|codePointAt.*0xE0100/ ascii
$eval_buf = /eval\(Buffer\.from/ ascii
$vs_range = /\xEF\xB8[\x80-\x8F]/ // UTF-8 for U+FE00-FE0F
condition:
2 of them
}
EOF
yara -r rules/glassworm.yar ./src
```
### 10. DNS & Network Monitoring
#### Passive DNS Integration
- Subscribe to Farsight Security or RiskIQ passive DNS feeds
- Query historical DNS data for infrastructure domains during IR
- Detect CNAME chains pointing to attacker-controlled servers
#### Threat Intelligence Feeds
| Feed | Coverage | Integration |
|------|----------|-------------|
| URLhaus | Known C2 domains | API, daily dump |
| Abuse.ch SSLBL | Malicious SSL certificates | IP blocklists |
| VirusTotal | Domain reputation | API |
| Custom | Typo variants of internal domains | Local script |
#### DNS Monitoring for CI/CD
- Log all DNS queries from runners to SIEM
- Block non-whitelisted external domains from runners
- Alert on edit distance < 2 from known infrastructure domains
---
## Hardening Actions
### Immediate (Already Applied)
```bash
npm config set ignore-scripts true
```
### Recommended for This Workstation
```bash
# 1. Install supply chain security tools
pacman -S syft grype cosign # SBOM, vuln scan, artifact verify
uv tool install semgrep # SAST with Unicode rules
# 2. Set up Unicode scanning as pre-commit hook
# (see GlassWorm section above for hook config)
# 3. Configure IDE visibility
# (see GlassWorm section for VS Code/Vim settings)
# 4. Audit systemd user services monthly
systemctl --user list-units --type=service --all
# 5. Network-level C2 blocking (optional)
# Block 45.148.10.212 and ICP boundary nodes if not needed
```
### CI/CD Hardening Checklist
- [ ] Pin all Actions to SHA256 (never tags)
- [ ] Use OIDC over long-lived secrets
- [ ] Block outbound to non-essential domains from runners
- [ ] Run sensitive builds in ephemeral environments
- [ ] Generate and verify SLSA provenance for built artifacts
- [ ] Sign container images with cosign
- [ ] Generate SBOM on every build (syft + grype)
- [ ] Run Nuclei templates against dependencies
- [ ] Enable Unicode scanning in CI pipeline
---
## Detection Patterns
### File System IOCs
```bash
# CanisterWorm
find ~ -name "pgmon*" -o -name "uv-proxy" -o -name "pglog" 2>/dev/null
# Unknown systemd user services
ls ~/.config/systemd/user/ | grep -v "default.target"
```
### Unicode IOCs (GlassWorm)
```bash
# VS1-VS16 range
grep -rP "[\x{FE00}-\x{FE0F}]" . --exclude-dir=node_modules --exclude-dir=.git
# Ideographic Variation Selectors
grep -rP "[\x{E0100}-\x{E01EF}]" . --exclude-dir=node_modules --exclude-dir=.git
# Decoder function pattern
grep -rP "codePointAt.*0xFE00|codePointAt.*0xE0100" . --include="*.js" --include="*.ts"
```
### Network IOCs
```bash
# TeamPCP C2
ss -ntu | grep -E "45.148.10.212"
getent hosts scan.aquasecurtiy.org
# ICP C2 (unexpected connections to Dfinity)
ss -ntu | grep -E "icp0\.io|dfinity"
```
---
## Workstation-Specific Implementation Priority
| Priority | Action | Effort | Impact |
|----------|--------|--------|--------|
| P0 | Pre-commit hook for Unicode scanning | 30min | Blocks GlassWorm |
| P0 | VS Code invisible char visibility | 5min | Visual detection |
| P1 | Monthly systemd service audit | 10min | Detects CanisterWorm |
| P1 | `npm config set ignore-scripts true` verify | 1min | Blocks script-based attacks |
| P2 | syft/grype SBOM scanning | 1hr setup | Continuous vuln monitoring |
| P2 | Nuclei C2 template scanning | 30min | Network IOC validation |
| P3 | Falco local agent setup | 2hr | Runtime memory/process monitoring |
| P3 | cosign artifact verification workflow | 1hr | Build integrity |
---
## References
- Upwind Security: Trivy/TeamPCP analysis
- EndorLabs: CanisterWorm + SANDWORM_MODE technical analysis
- Aikido Security: GlassWorm Unicode campaign tracking
- Unit42 (Palo Alto): Shai-Hulud 2.0 npm supply chain attack
- Chainguard: npm supply chain hardening and OIDC future
- CISA: GitHub Actions Security Hardening Guidance
- Cilium/Tetragon: eBPF Security Enforcement documentation
- Falco: Runtime security rules and best practices
- SLSA v1.2: slsa.dev/spec/v1.2
- Sigstore: sigstore.dev
- NIST SSDF v1.1: Secure Software Development Framework