# Docker Digest Update Process

**Last Updated:** 2026-04-18  
**Owner:** DevOps Engineer  
**Related:** MIN-82 (Docker SHA256 pinning)

---

## Overview

All MINION Docker base images are pinned to **SHA256 digests** to prevent supply chain attacks. This document describes how to safely update these digests when upstream images release security patches or new versions.

---

## When to Update

### Required Updates
- **Monthly security cycle** (first Monday of each month)
- **CVE remediation** (when `node:22-bookworm` or `debian:bookworm-slim` publish security fixes)
- **Major releases** (before production deployments)

### Optional Updates
- **Performance improvements** in upstream images
- **Debian/Node.js minor version bumps** (22.1 → 22.2, etc.)

---

## Affected Files

| File | Base Image | Current Digest (2026-04-18) |
|------|------------|----------------------------|
| `Dockerfile` | `node:22-bookworm` | `sha256:ecabd1cb6956d7acfffe8af6bbfbe2df42362269fd28c227f36367213d0bb777` |
| `Dockerfile.sandbox` | `debian:bookworm-slim` | `sha256:4724b8cc51e33e398f0e2e15e18d5ec2851ff0c2280647e1310bc1642182655d` |
| `Dockerfile.sandbox-browser` | `debian:bookworm-slim` | `sha256:4724b8cc51e33e398f0e2e15e18d5ec2851ff0c2280647e1310bc1642182655d` |
| `Dockerfile.sandbox-common` | `minion-sandbox:bookworm-slim` | (internal, inherits from `Dockerfile.sandbox`) |

---

## Step-by-Step Update Procedure

### 1. Check for New Upstream Digests

```bash
# Node.js 22 (Bookworm)
docker pull node:22-bookworm
docker inspect node:22-bookworm | jq -r '.[0].RepoDigests[0]'

# Debian Bookworm Slim
docker pull debian:bookworm-slim
docker inspect debian:bookworm-slim | jq -r '.[0].RepoDigests[0]'
```

**Expected output:**
```
node:22-bookworm@sha256:<new_digest>
debian:bookworm-slim@sha256:<new_digest>
```

**If digest unchanged:** No update needed. Exit process.

---

### 2. Update Dockerfiles

Replace the SHA256 digests in each file:

#### Dockerfile
```dockerfile
# Before:
FROM node:22-bookworm@sha256:ecabd1cb6956d7acfffe8af6bbfbe2df42362269fd28c227f36367213d0bb777

# After:
FROM node:22-bookworm@sha256:<new_digest>
```

#### Dockerfile.sandbox
```dockerfile
# Before:
FROM debian:bookworm-slim@sha256:4724b8cc51e33e398f0e2e15e18d5ec2851ff0c2280647e1310bc1642182655d

# After:
FROM debian:bookworm-slim@sha256:<new_digest>
```

#### Dockerfile.sandbox-browser
(Same as `Dockerfile.sandbox`)

#### Dockerfile.sandbox-common
(Inherits from `minion-sandbox:bookworm-slim`, no direct change needed)

---

### 3. Verify Bun/Homebrew Install Pins

Check if Bun or Homebrew have published new security releases:

```bash
# Check Bun latest stable version
curl -s https://api.github.com/repos/oven-sh/bun/releases/latest | jq -r '.tag_name'

# Check Homebrew install script commit
curl -s https://api.github.com/repos/Homebrew/install/commits/HEAD | jq -r '.sha'
```

**If Bun version changed:** Update `BUN_VERSION` in `Dockerfile` and `Dockerfile.sandbox-common`.

**If Homebrew commit changed:** Update `BREW_INSTALL_COMMIT` in `Dockerfile.sandbox-common`.

---

### 4. Test Builds Locally

```bash
cd minion-ai

# Build gateway image
docker build -f Dockerfile -t minion-gateway:digest-test .

# Build sandbox images
docker build -f Dockerfile.sandbox -t minion-sandbox:digest-test .
docker build -f Dockerfile.sandbox-browser -t minion-sandbox-browser:digest-test .
docker build -f Dockerfile.sandbox-common \
  --build-arg BASE_IMAGE=minion-sandbox:digest-test \
  -t minion-sandbox-common:digest-test .
```

**If builds fail:** 
- Check Docker BuildKit cache (try `--no-cache`)
- Verify digest matches `docker pull` output
- Check upstream breaking changes in release notes

---

### 5. Runtime Verification

```bash
# Gateway: Verify Node + Bun runtime
docker run --rm minion-gateway:digest-test node --version
docker run --rm minion-gateway:digest-test bun --version

# Sandbox: Verify core tools
docker run --rm minion-sandbox:digest-test bash -c 'git --version && curl --version'

# Sandbox-common: Verify dev tools
docker run --rm minion-sandbox-common:digest-test bash -c 'bun --version && brew --version && node --version'
```

**Expected:** All commands return version numbers without errors.

---

### 6. Security Validation

```bash
# Verify no floating tags remain
cd minion-ai
grep -E '^FROM [^@]+$' Dockerfile* && echo "❌ FAIL: Floating tag found" || echo "✅ PASS: All images pinned"

# Verify curl | bash is pinned or removed
grep -E 'curl.*\|.*bash' Dockerfile* | grep -v 'BUN_VERSION\|BREW_INSTALL_COMMIT' && echo "⚠️ WARN: Unverified curl | bash" || echo "✅ PASS: All curl | bash pinned"
```

---

### 7. Commit and Create PR

```bash
# Create security branch
git checkout -b security/update-docker-digests-$(date +%Y-%m-%d)

# Stage changes
git add Dockerfile Dockerfile.sandbox Dockerfile.sandbox-browser Dockerfile.sandbox-common
git add docs/security/DOCKER_DIGEST_UPDATE.md

# Commit with detailed message
git commit -m "security: update Docker base image digests ($(date +%Y-%m-%d))

- node:22-bookworm → sha256:<new_digest>
- debian:bookworm-slim → sha256:<new_digest>
- BUN_VERSION → <new_version> (if updated)
- BREW_INSTALL_COMMIT → <new_commit> (if updated)

Addresses: MIN-82 (ongoing maintenance)
Tested: Local builds + runtime verification passed
Security: Reviewed upstream changelogs for breaking changes"

# Push and create PR
git push origin security/update-docker-digests-$(date +%Y-%m-%d)
gh pr create --title "security: update Docker digests ($(date +%Y-%m-%d))" \
  --body "Monthly security digest update. See commit message for details." \
  --label "security,devops,docker"
```

---

### 8. Request Security Review

Tag CTO and Security Auditor in PR:
```
@CTO @Security-Auditor: Monthly Docker digest update ready for review.

Changes:
- ✅ All base images pinned to latest SHA256 digests
- ✅ Bun/Homebrew pins updated (if applicable)
- ✅ Local builds + runtime verification passed
- ✅ No floating tags or unverified curl | bash

Upstream changelogs reviewed for breaking changes: none found.
```

---

### 9. Merge and Deploy

After approval:
```bash
# Merge to DEV first
gh pr merge --squash --delete-branch

# Monitor CI builds
gh run watch

# After CI passes, merge DEV → main (per branch flow)
git checkout main
git pull origin main
git merge origin/DEV
git push origin main
```

**Production deployment:** Gateway will auto-rebuild via CI/CD on Netcup VPS.

---

## Rollback Plan

If builds fail or runtime issues occur **after merge**:

```bash
# Revert the merge commit
git revert <merge-commit-sha>
git push origin main

# Restore previous digests temporarily
# (git will restore old Dockerfile content)

# Investigate root cause
docker inspect node:22-bookworm@sha256:<new_digest>
# Check upstream release notes for breaking changes
```

**Why safe:** SHA256 digests are immutable. If local build passed, production build will be identical. Rollback restores exact previous state.

---

## Automation Opportunities (Future)

### Dependabot-Style Digest Updates
- **Tool:** Renovate Bot or custom GitHub Action
- **Frequency:** Weekly scan for new digests
- **Auto-PR:** Create PR with digest updates + changelog summary
- **Status:** MIN-83 (future improvement)

### CI Linter for Floating Tags
- **Tool:** `hadolint` or custom script
- **Check:** Fail CI if `FROM <image>:<tag>` detected (without `@sha256:`)
- **Status:** MIN-83 (future improvement)

---

## Troubleshooting

### Build Fails with "manifest unknown"
**Cause:** Digest is for wrong architecture (amd64 vs arm64).

**Fix:** 
```bash
docker pull --platform linux/amd64 node:22-bookworm
docker inspect node:22-bookworm | jq -r '.[0].RepoDigests[0]'
```

### Bun Install Fails
**Cause:** Bun version pinned to deprecated release.

**Fix:** Check latest stable version:
```bash
curl -s https://api.github.com/repos/oven-sh/bun/releases | jq -r '.[0].tag_name'
```
Update `BUN_VERSION` in Dockerfiles.

### Homebrew Install Script Changed
**Cause:** Upstream breaking change in Homebrew installer.

**Fix:** Review commit diff:
```bash
curl -s "https://api.github.com/repos/Homebrew/install/compare/<old_commit>...<new_commit>"
```
If breaking change detected, coordinate with CTO before updating.

---

## References

- **MIN-82:** Original security fix for Docker digest pinning
- **CIS Docker Benchmark:** Recommends immutable base images
- **SLSA Framework:** Supply chain security best practices
- **Node.js Docker Hub:** https://hub.docker.com/_/node
- **Debian Docker Hub:** https://hub.docker.com/_/debian
- **Bun Releases:** https://github.com/oven-sh/bun/releases
- **Homebrew Install:** https://github.com/Homebrew/install

---

## Contact

- **Owner:** DevOps Engineer (agent 68c8d493-858d-4ed5-a1b0-d60020177502)
- **Escalation:** CTO
- **Security Issues:** Security Auditor + CTO

---

_Last digest update: 2026-04-18_  
_Next scheduled update: 2026-05-06 (first Monday of May)_
