Every finding in this post is empirical — captured from a real deployment against a Big Bang instance with Istio, Kyverno, cosign image signing, and CycloneDX SBOM attestation enforced.
The application: a Rails deployment to Big Bang
OpenProject 17.7.2 — an open-source project management platform. Ruby 4.0.6 on Rails 8.1.3.1, Angular frontend, PostgreSQL 17 with custom extensions, Redis-compatible cache, S3-compatible object storage, and a Node.js WebSocket service (Hocuspocus) for real-time collaborative editing. Three deployments plus a migration Job.
It is also the project management component of openDesk, the sovereign workplace suite that BWI — the Bundeswehr's IT provider — adopted under a seven-year framework agreement. A NATO member's armed forces already standardize on this application.
On paper, it's ready to deploy. Docker support. Kubernetes documentation. Helm chart.
What I predicted vs. what actually happened
Before deploying, I modeled the expected findings based on architecture analysis. The model predicted 27–32 discrete findings across six failure classes.
| Prediction | Result | Notes |
|---|---|---|
| Runs as root | Refuted | Non-root, uid 1000 |
| Hocuspocus ~900 MB, 150+ CVEs | Refuted | 492 MB, 14 CVEs — already built on distroless |
| No managed PostgreSQL | Refuted | Platform provides managed PostgreSQL 17 |
| Extensions need custom PG build | Confirmed partial | Extensions trusted but require DBA pre-creation (superuser) |
| Need Memcached container | Refuted | Native Redis-compatible cache support |
| S3 not available | Refuted | S3-compatible storage available |
| TLS conflict with mesh | Refuted | Application does not terminate TLS |
| Writable rootfs needed | Confirmed | Three writable paths, plus a Ruby /tmp trap |
| ~800 MB, 200+ CVEs | Confirmed — worse | 1.5 GB, 670 CVEs |
| FIPS compatibility | Scoped | Two code changes identified |
The model was wrong in both directions. It overestimated infrastructure problems and underestimated image vulnerability severity. That's the point of deploying instead of modeling.
Total findings: 10
| Category | Total | Resolved | Remaining |
|---|---|---|---|
| Configuration | 7 | 7 | 0 |
| Vulnerability posture | 1 | 1 | 0 |
| FIPS | 2 | 2 | 0 |
| Total | 10 | 10 | 0 |
All findings resolved. No application code changes required for deployment.
The deployment findings
All workloads passed 39 Kyverno admission policies, cosign signature verification, and CycloneDX SBOM attestation. The application is serving on the platform.
| Workload | State | Notes |
|---|---|---|
openproject-web |
Running | Puma, 2 workers, port 8080 |
openproject-worker |
Running | GoodJob background processor |
openproject-hocuspocus |
Running | Collaborative editing, port 1234 |
openproject-migrate |
Completed | ~1,500 Rails migrations |
Every blocker was configuration. None required application code changes.
Finding 1 — Secrets silently absent at runtime. The entrypoint does not load platform-injected secrets. The injector reports success; the application receives no environment variables. Silent failure — the symptom is a database connection error, not a secrets error.
Finding 2 — Ruby rejects the default temporary directory. Ruby's Dir.tmpdir skips directories with incompatible permissions. Rails fails at boot with no indication of the cause.
Finding 3 — Collaborative editor port mismatch. Hocuspocus listens on port 1234, not the documented 3000. Health checks kill a healthy process.
Finding 4 — Database migrations pending. ~1,500 migrations required. The application will not start without them. The vendor assumes you run them manually — no shell access on a hardened platform.
Finding 5 — Cache key prefix mismatch. Every cache read/write denied. The application's default cache prefix does not match the provisioned credentials.
Finding 6 — Real-time channel prefix hardcoded. ActionCable's channel prefix is a literal string in application config — separate from the cache prefix. Teams fix Finding 5 and miss this one.
Finding 7 — Storage backend crashes at boot without credentials. The S3 backend initializes eagerly, not lazily. The application crashes before reaching the code that uses storage.
Each finding surfaced serially. Each fix revealed the next failure. Without the lab, each would be a separate submission to the target platform's review cadence.
The production blocker: 685 CVEs → 0 on a hardened Ruby image
| Image | Base | Size | Critical | High | Medium | Low | Unknown | Total |
|---|---|---|---|---|---|---|---|---|
openproject:17.7.2-slim |
ruby:4.0.6-slim-trixie (Debian) |
1.5 GB | 28 | 96 | 171 | 306 | 69 | 670 |
hocuspocus:17.7.1 |
distroless/nodejs24:nonroot |
492 MB | 0 | 0 | 7 | 7 | 0 | 14 |
28 criticals blocked the Rails image from production — no override. 96 highs required explicit recorded acceptance. All CVEs were in the Debian base and Ruby/Node.js toolchain, not in application code.
After hardening
| Image | Base | Size | Critical | High | Total | Delta |
|---|---|---|---|---|---|---|
Rails (slim-dev) |
cgr.dev/chainguard/ruby:latest-dev (wolfi) |
2.6 GB | 0 | 0 | 0 | −670 |
Rails (slim) |
cgr.dev/chainguard/ruby:latest (wolfi, distroless) |
1.28 GB | 0 | 0 | 0 | −670 |
| Hocuspocus | cgr.dev/chainguard/node:latest (wolfi, distroless) |
539 MB | 0 | 0 | 0 | −15 |
685 CVEs eliminated. 0 residual. Both images pass the production vulnerability gate.
The Dockerfile provides two runtime targets for Rails:
slim-dev— has bash, supports entrypoint scripts that source secrets. 2.6 GB. Verified end-to-end.slim— distroless, no shell, no package manager. 1.28 GB. Verified end-to-end.
Both targets scan identically at 0 CVEs. Both verified with PostgreSQL, Redis-compatible cache, migrations (~1,500), database seed, and HTTP serving.
FIPS 140: two bounded code changes
Most of OpenProject's cryptography is already FIPS-compatible — AES-256-CBC/GCM for encryption, HMAC-SHA256 for tokens and sessions, PBKDF2 for key derivation, OpenSSL 3.x for TLS.
Two operations break under FIPS enforcement:
| Component | Was | Now | Status |
|---|---|---|---|
| Password hashing | bcrypt (Blowfish) — not FIPS-approved | PBKDF2-HMAC-SHA256 (600,000 iterations) | Done — in fork, verified |
| Attachment checksum | MD5 — not FIPS-approved | SHA-256 | Done — single call site |
Both are implemented in the assessment fork. Existing bcrypt passwords migrate transparently on next login — same pattern as the existing SHA-1 → bcrypt migration already in production.
Code quality
| Scanner | Findings | Notes |
|---|---|---|
| Semgrep | 986 | Output-escaping patterns typical of large Rails applications |
| Brakeman | 55 (1 high-confidence, 2 RCE) | Vendor maintains a suppression file for known false positives |
Documented for acknowledgement. Remediation is the vendor's responsibility. The high-confidence and RCE findings warrant review for platform admission.
What was eliminated
Work that didn't need to happen
| Planned work | Why unnecessary | Days avoided | Cost avoided (GSA $175/hr) |
|---|---|---|---|
| Rebuild image to run non-root | Already non-root, uid 1000 | 2–3 | $2,800–$4,200 |
| Rebuild Hocuspocus on hardened base | Already hardened, 0 criticals | 1–2 | $1,400–$2,800 |
| Containerize PostgreSQL | Platform provides managed PostgreSQL 17 | 3–5 | $4,200–$7,000 |
| Build cache sidecar | Native Redis-compatible support | 1–2 | $1,400–$2,800 |
| Design TLS passthrough for mesh | Application does not terminate TLS | 0.5–1 | $700–$1,400 |
| Total | 8–13 days | $11,000–$18,000 |
These figures use the GSA Alliant 3 / OASIS+ midpoint for cleared DevSecOps engineers ($175/hr). On the commercial market, cleared engineers with this profile bill $200–$325/hr — pushing the wasted spend to $16,000–$34,000.
Work that only deployment revealed
| Finding | Why invisible without deployment |
|---|---|
| Secrets silently absent | Injector and application both correct in isolation; gap is between them |
| Ruby rejects default temp directory | Language-specific runtime behavior, not documented |
| Hocuspocus on undocumented port | Only visible in the container's startup log |
| Migrations not in deployment manifests | Application assumes separate execution |
| Cache prefix outside credential scope | Correct for the app, wrong for the platform |
| Channel prefix hardcoded | Separate from cache prefix — teams fix one and miss the other |
| Storage crashes without credentials | Eager initialization, fails before the code that uses storage |
Authorization lifecycle cost
Without the image hardening, each of 685 CVEs requires a security impact statement — approximately 1 hour each for initial writing, then re-validation on a severity-driven schedule:
| Severity | CVEs | Re-validation window | 5-year hours | Cost at $175/hr |
|---|---|---|---|---|
| Critical | 28 | 30 days | ~840 | ~$147,000 |
| High | 96 | 90 days | ~2,880 | ~$504,000 |
| Medium | 171 | 180 days | ~860 | ~$150,000 |
| New CVEs (~20/yr) | — | On discovery | ~100 | ~$17,500 |
| Initial statements | 685 | One-time | ~685 | ~$120,000 |
| 5-year total | ~5,365 | ~$938,500 |
That's nearly $1M in CVE documentation labor at GSA rates — and GSA rates are the floor. Cleared cybersecurity analysts on the commercial market command $200–$325/hr, which pushes the 5-year obligation past $1.3M. With 0 residual CVEs, this entire obligation is eliminated — not deferred, eliminated.
What the study delivered
Every item below is working code or a tested configuration — not a recommendation.
| Deliverable | Description |
|---|---|
| Hardened Dockerfiles | Both images rebuild at 0 CVEs. Multi-stage, Chainguard wolfi. |
| FIPS code changes | bcrypt → PBKDF2-HMAC-SHA256, MD5 → SHA-256. In fork, verified. |
| CI/CD pipeline | Builds hardened images, pushes through the image gate automatically. |
| Operational manifests | 12 files (840 lines). Seed Job, break-glass credential reset, migration Job. |
| Configuration playbook | 7 findings, each with the exact resolution. |
| Egress profile | 8 destination categories. Minimum allow-list: disable Gravatar for zero egress. |
| Code quality baseline | Semgrep + Brakeman scans for platform admission. |
Remaining effort to deploy on a target platform
| Phase | Engineering effort | Notes |
|---|---|---|
| Platform provisioning | 1–2 days | Namespace, database, cache, secrets, image mirroring |
| Configuration + deployment | 1–2 days | Apply the 7 documented configurations |
| OIDC + SMTP | 1 day | Enterprise license required for OIDC |
| Operational verification | 1 day | Seed, break-glass, multi-replica |
4–6 days of engineering. Calendar time depends on the target platform's review cadence.
Build your own environment or deploy to an existing one?
| Your own enclave from scratch | Existing accredited platform | |
|---|---|---|
| Infrastructure | Build and maintain hardened K8s, Istio, Kyverno, monitoring, logging, storage | Already exists, already authorized |
| Authorization | Full ATO from zero: 12–18 months, $500K–$2M+ in documentation and process | Inherit platform authorization, application-level CtF/ATO in weeks to months |
| Staffing | Cleared DevSecOps team to build and operate | Application hardening only |
| Ongoing | You own patching, continuous monitoring, incident response, re-authorization | Platform operator handles infrastructure security |
| First-year cost | $2–5M+ | $50–200K for application hardening + platform fees |
OpenProject's requirements — PostgreSQL, Redis-compatible cache, S3-compatible storage, OIDC — are standard managed services on existing platforms. A dedicated enclave for a single project management application would be disproportionate.
Existing platforms here means Platform One's Party Bus, Second Front's Game Warden, or a program-office Big Bang environment. Millabs has taken a commercial application through Game Warden to IL-4 and TOP SECRET on JWICS. Second Front is also bringing Game Warden to AWS European Sovereign Cloud, with ten customers prepared to deploy — relevant to any program with a coalition or OCONUS footprint.
The takeaway
- "Runs in Docker" and "runs in a hardened enclave" are separated by 10 findings and 4–6 days of engineering — not the 27–32 findings and 6–10 weeks the model predicted
- Architecture analysis overestimated by 8–13 days ($11,000–$18,000 at GSA rates) of unnecessary work and underestimated image vulnerability severity by 3x
- 685 → 0 CVEs with a base image swap — eliminating ~$940,000 in authorization maintenance over 5 years ($1.3M+ at commercial cleared rates)
- The 7 runtime findings were invisible without deployment — every one of them would have been a separate rejection cycle on a live platform
- The study delivered working code, not recommendations. The only remaining gate is procurement (Enterprise license for OIDC and antivirus)
Robert Burckner is the founder of Millabs Corporation. This deployment was performed in a privately operated, unaccredited Big Bang instance. No government data was used. OpenProject is open-source software licensed under GPL-3.0.
If your product needs to deploy into a hardened DoW enclave, contact Millabs for a fit screen.
If you are a program office weighing OpenProject for your own enclave, the deployment above is reproducible and the findings transfer. Millabs scopes that work, and will operate the result at any impact level — CUI at IL-4/IL-5, Secret at IL-6, Top Secret on JWICS — for programs that would rather not staff it.