Posted on
Artificial Intelligence

Artificial Intelligence Risk Assessments

Author
  • User
    linuxbash
    Posts by this author
    Posts by this author

Artificial Intelligence Risk Assessments on Linux: A Hands-On Bash Guide

AI is now part of your production stack—even if you didn’t get a memo. A Jupyter notebook turned microservice, a container running a text-generation API, a “quick” embedding job shipping nightly: each can quietly expand your attack surface and compliance exposure. The good news? You can treat AI like any other critical workload and assess it—systematically—using the Linux command line you already know.

This guide shows how to run a practical AI risk assessment from your terminal. You’ll inventory assets, scan supply chains, check code and secrets, and harden runtime—all with reproducible Bash steps. By the end, you’ll have a repeatable process and commands you can drop into CI, cron, or a Makefile.

Why AI Risk Assessments Matter (Even for Bash-first Teams)

  • New failure modes: Prompt injection, data leakage, model tampering, dependency drift, and jailbreaks add to traditional issues like CVEs and misconfig.

  • Regulatory pressure: NIST AI RMF, ISO/IEC 23894, and sector rules increasingly expect documented risks, controls, and traceability.

  • Shared infrastructure: AI services often run in the same clusters and nodes as everything else—cross-contamination and privilege risks are real.

  • Fast-moving supply chain: Models, datasets, and Python packages change rapidly; “it worked last week” isn’t a control.

Treating AI systems with the same rigor as other services—plus a few AI-specific checks—keeps you ahead of surprises.


Prerequisites: Install the Tools

We’ll use standard packages and containerized scanners so you can run the same commands across distros.

Install Podman, jq, curl, pipx, and auditd:

Debian/Ubuntu (apt)

sudo apt update
sudo apt install -y podman jq curl pipx auditd

Fedora/RHEL/CentOS (dnf)

sudo dnf install -y podman jq curl pipx audit

openSUSE (zypper)

sudo zypper refresh
# pipx may be named pipx or python3-pipx depending on your version
sudo zypper install -y podman jq curl pipx || sudo zypper install -y python3-pipx
sudo zypper install -y audit

Optional: Ensure pipx is on your PATH

pipx ensurepath
# restart your shell if needed

Enable auditd so runtime access is recorded:

sudo systemctl enable --now auditd

Note: We’ll use containerized tools (via Podman) for SBOM and vuln scans, avoiding extra native installs.


Step 1 — Inventory Your AI Assets (Models, Datasets, Code, Endpoints)

You can’t assess what you don’t know. Start by enumerating processes, containers, packages, and hardware.

List likely AI-related processes:

ps aux | egrep -i 'python|torch|transformers|tensorflow|onnx|triton|vllm|ray|textgen' | grep -v egrep

Check running containers/images:

podman ps --format json | jq -r '.[].Image' | sort -u
podman images --format json | jq -r '.[].Repository + ":" + .Tag' | sort -u

Capture Python dependencies in your app directory (if you have a virtualenv, activate it first):

python3 -m pip freeze > requirements.lock.txt 2>/dev/null || true

Optional: GPU visibility (if present)

if command -v nvidia-smi >/dev/null 2>&1; then
  nvidia-smi --query-gpu=name,driver_version --format=csv
fi

Produce a quick SBOM for your code directory using Syft (containerized):

# From your project root
podman run -t --rm -v "$PWD":/work -w /work docker.io/anchore/syft:latest dir:. -o json > sbom.json
jq '.artifacts | length as $n | "SBOM artifacts: \($n)"' sbom.json

Tip: Store these outputs (process list, images, SBOM) with timestamps to track drift over time.


Step 2 — Build a Lightweight Risk Register and Score It

Keep a machine-readable risk list with likelihood, impact, and owner. Example JSON:

cat > ai_risks.json <<'JSON'
{
  "risks": [
    {
      "id": "R-001",
      "title": "Prompt injection causing data exfiltration",
      "likelihood": "medium",
      "impact": "high",
      "owner": "appsec",
      "controls": ["output filtering", "domain-restricted retrieval", "rate limits"]
    },
    {
      "id": "R-002",
      "title": "Vulnerable Python dependency in inference service",
      "likelihood": "high",
      "impact": "medium",
      "owner": "platform",
      "controls": ["SBOM tracking", "vuln scan in CI", "pip hash pins"]
    },
    {
      "id": "R-003",
      "title": "Model file tampering on disk",
      "likelihood": "low",
      "impact": "high",
      "owner": "platform",
      "controls": ["read-only FS", "auditd watch", "checksum on startup"]
    }
  ]
}
JSON

Filter for your top items:

jq -r '.risks[] | select((.likelihood=="high") or (.impact=="high")) | "\(.id): \(.title) [owner=\(.owner)]"' ai_risks.json

This register ties the evidence you’ll collect (SBOMs, scans, audit logs) to an assurance story others can review.


Step 3 — Scan the AI Supply Chain (SBOM + Vulnerabilities)

You’ve created an SBOM. Now turn it into action with a vulnerability scan.

Scan an existing SBOM using Grype (containerized):

podman run -t --rm -v "$PWD":/work -w /work docker.io/anchore/grype:latest sbom:sbom.json -o table

Scan a container image used for inference:

IMG="your-registry/ai-inference:latest"
podman pull "$IMG"
podman run -t --rm docker.io/anchore/grype:latest "$IMG" -o table

Enforce pins and hashes in Python to reduce drift:

# Generate hashes for requirements (from a clean env)
python3 -m pip hash -r requirements.lock.txt
# Or recreate with pip-compile if you use pip-tools (recommended in CI)

Real-world win: Teams often discover a handful of “it slipped in” packages (e.g., transitive urllib3 or Jinja2 versions) that are exploitable. Bake the SBOM+vuln scan into CI for every image and push.


Step 4 — Check Code and Secrets (Before Models Touch Data)

Scan Python code for common issues with Bandit:

Install Bandit via pipx:

  • apt
sudo apt install -y pipx
pipx ensurepath
pipx install bandit
  • dnf
sudo dnf install -y pipx
pipx ensurepath
pipx install bandit
  • zypper
sudo zypper install -y pipx || sudo zypper install -y python3-pipx
pipx ensurepath
pipx install bandit

Run Bandit:

bandit -r . -f screen

Scan for secrets with Gitleaks (containerized):

# From the repo root (best results in a git repo)
podman run -t --rm -v "$PWD":/repo -w /repo docker.io/gitleaks/gitleaks:latest detect --report-format=json --report-path=gitleaks.json
jq '.findings | length as $n | "Gitleaks findings: \($n)"' gitleaks.json

Quick pattern check on logs (helps catch accidental PII routing to logs):

grep -RInE 'api[_-]?key|secret|password|ssn|passport|private[_-]?key' /var/log/llm_app.log 2>/dev/null || true

Real-world win: Gitleaks routinely catches long-lived API keys lurking in model-serving repos or notebooks—fixing one of the fastest paths to data exfil.


Step 5 — Harden Runtime and Monitor Access

Lock down containers that serve models. A few Podman flags go a long way:

Offline or proxied inference (no blind egress):

podman run --rm \
  --network=none \
  --read-only --tmpfs /tmp:rw,size=256m \
  --cap-drop=ALL --security-opt=no-new-privileges \
  -v "$PWD/model:/opt/model:ro" \
  your-registry/ai-inference:stable

If egress is required, prefer an egress proxy with allowlists over raw internet access.

Track model file access with auditd:

# Watch model directory for read/write/attr events
sudo bash -lc 'echo "-w /opt/model -p rwa -k model_access" > /etc/audit/rules.d/99-model.rules'
sudo augenrules --load || sudo service auditd restart

# Test and view events
sudo ausearch -k model_access | aureport -f -i

Add checksums at startup to detect tampering:

# Run at container/service start
find /opt/model -type f -name '*.pt' -o -name '*.bin' -o -name '*.onnx' -print0 \
 | xargs -0 sha256sum > /run/model.sha256

# Verify periodically
sha256sum -c /run/model.sha256 | grep -v ': OK' && echo "ALERT: Model file drift detected"

Redaction on output (defense-in-depth against prompt injection exfil):

# Simple output filter example
your_llm_infer_cmd | sed -E 's/(api[_-]?key|password|secret)\s*[:=]\s*[A-Za-z0-9_\-]{16,}/[REDACTED]/gi'

Real-world win: A read-only root with tmpfs for scratch plus no-new-privileges stops a surprising number of “accidental write” and “just curl it” failure modes.


Putting It Together: A Minimal, Repeatable Flow

  • Inventory weekly: processes, images, SBOMs

  • Scan always: SBOM and images in CI; Bandit and Gitleaks on PRs

  • Enforce runtime: hardened Podman flags by default, auditd watches for model files

  • Track risks: update ai_risks.json when you add models, datasets, or endpoints; link CI artifacts (logs, SBOMs, reports)

Example one-shot script you can adapt:

#!/usr/bin/env bash
set -euo pipefail

TS="$(date -u +%Y%m%dT%H%M%SZ)"
OUT="risk-evidence-$TS"
mkdir -p "$OUT"

ps aux > "$OUT/processes.txt"
podman ps --format json > "$OUT/podman-ps.json"
podman images --format json > "$OUT/podman-images.json"

if [ -d .git ]; then
  podman run -t --rm -v "$PWD":/repo -w /repo docker.io/gitleaks/gitleaks:latest detect --report-format=json --report-path="/repo/$OUT/gitleaks.json" || true
fi

podman run -t --rm -v "$PWD":/work -w /work docker.io/anchore/syft:latest dir:. -o json > "$OUT/sbom.json"
podman run -t --rm -v "$PWD/$OUT":/work -w /work docker.io/anchore/grype:latest sbom:sbom.json -o json > "$OUT/vulns.json"

[ -x "$(command -v bandit)" ] && bandit -r . -f json -o "$OUT/bandit.json" || true

jq '.risks[] | {id, title, owner}' ai_risks.json 2>/dev/null | tee "$OUT/risks.txt" || echo "No ai_risks.json found" | tee -a "$OUT/risks.txt"

echo "Evidence in: $OUT"

Conclusion and Next Steps

AI risk isn’t mysterious—it’s assessable. With a Linux-first approach you can:

  • Know what you run (inventory + SBOM)

  • Know what’s risky (scans + risk register)

  • Control how it runs (hardened containers + audit trails)

Next steps:

  • Automate the flow in CI and a weekly cron job.

  • Treat ai_risks.json as a living document and link each risk to the evidence you generate.

  • Expand checks with domain-specific tests (e.g., red-teaming prompts, dataset lineage checks).

If you want a follow-up article with a Makefile-driven starter kit and CI snippets for GitHub/GitLab, let me know—I’ll publish a ready-to-clone repo.