Title: Extra CA bundle in builds and containers; tests for secrets on tmpfs (Spinbox integration) · Issue #50 · spin-stack/devcontainer-cli · GitHub
Open Graph Title: Extra CA bundle in builds and containers; tests for secrets on tmpfs (Spinbox integration) · Issue #50 · spin-stack/devcontainer-cli
X Title: Extra CA bundle in builds and containers; tests for secrets on tmpfs (Spinbox integration) · Issue #50 · spin-stack/devcontainer-cli
Description: Spinbox is adding devcontainer support and a new secrets model (installation → team → user scopes). Builds and containers run inside a workspace VM whose outbound traffic goes through an egress proxy. For hosts where a rule injects a cre...
Open Graph Description: Spinbox is adding devcontainer support and a new secrets model (installation → team → user scopes). Builds and containers run inside a workspace VM whose outbound traffic goes through an egress pro...
X Description: Spinbox is adding devcontainer support and a new secrets model (installation → team → user scopes). Builds and containers run inside a workspace VM whose outbound traffic goes through an egress pro...
Opengraph URL: https://github.com/spin-stack/devcontainer-cli/issues/50
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Extra CA bundle in builds and containers; tests for secrets on tmpfs (Spinbox integration)","articleBody":"Spinbox is adding devcontainer support and a new secrets model (installation → team → user scopes). Builds and containers run inside a workspace VM whose outbound traffic goes through an egress proxy. For hosts where a rule injects a credential, the proxy terminates TLS with its own CA; every other host is relayed as bytes. Spinbox will call this CLI with:\n\n- `--secrets-file` pointing at a JSON file on tmpfs, holding the workspace's resolved `env` secrets;\n- `DOCKER_CONFIG` pointing at a tmpfs directory when a registry credential is delivered as a file;\n- `TMPDIR` on tmpfs.\n\nNothing secret may reach the workspace disk, because a prebuild's disk becomes a snapshot shared with a team.\n\nMost of this already works. One feature is missing, and three behaviours need tests so they don't regress.\n\n## 1. Trust an extra CA bundle in builds and in the container (missing)\n\nA `RUN` step, or a Feature's `install.sh`, that calls a host the proxy injects for fails TLS: the build container trusts only the image's own CAs. The same is true for processes in the running container.\n\nProposed: `--ca-bundle \u003cfile>` on `build`, `up` and `run-user-commands` (name open). The file is a full PEM bundle (system CAs + the proxy's CA), so tools that replace the system pool keep working.\n\n- **Feature install RUNs** (the CLI writes these, in `imagemeta/extend.go`): mount the bundle as a BuildKit secret, as is already done for `--secrets-file` ids, e.g. `--mount=type=secret,id=devcontainer-ca-bundle,target=/run/devcontainer/ca-bundle.crt`, and set for that RUN only: `SSL_CERT_FILE`, `NODE_EXTRA_CA_CERTS`, `REQUESTS_CA_BUNDLE`, `CURL_CA_BUNDLE`, `GIT_SSL_CAINFO`.\n- **User Dockerfile**: the CLI cannot change its RUNs. Pass the same secret id to buildx so a Dockerfile can opt in with `RUN --mount=type=secret,id=devcontainer-ca-bundle,target=...`, and document it.\n- **Running container** (`up`): bind-mount the bundle read-only at the same path and set the same variables in the container's environment, so lifecycle hooks and the user's shells trust it.\n- Mount it, never `COPY` it: the image must be the same with and without a bundle, so the cache key and the prebuilt image don't depend on the proxy. The CA is public, so the reason is reproducibility, not secrecy.\n- Without buildx: a warning, as `buildxSecrets` does today.\n\nTests: a Feature RUN and an opted-in Dockerfile RUN reach an HTTPS server signed by a test CA, and fail without the flag. The built image's layers and config don't contain the bundle. In the container, `curl` and `node` trust the server.\n\n## 2. `DOCKER_CONFIG` on tmpfs (works; needs a test)\n\n`oci/auth.go:76` and `docker/context.go:51` already honour `DOCKER_CONFIG`. Add a test that registry resolution and `bridgeBuildAuth` read credentials from a `DOCKER_CONFIG` directory outside `$HOME`, where `config.json` is a symlink to another directory. Spinbox serves it from a FUSE or tmpfs mount, so it never puts a file at `~/.docker/config.json`; its prebuild scan flags that path whatever it contains.\n\n## 3. `--secrets-file` on `up` (works; needs a test)\n\n`up` already passes the file to the Dockerfile and Feature builds (`up.go:1408`) and to lifecycle hooks (`up.go:1216`). Add one end-to-end test that `up --secrets-file` gives both a `RUN --mount=type=secret,id=K` and a `postCreateCommand` the value, and that the value is in no image layer, no image config (`docker history`) and no container label.\n\n## 4. Temporary build auth follows `TMPDIR` (works; document it)\n\n`ResolveBuildAuth` writes the resolved registry credentials to `os.MkdirTemp(\"\")` and removes them after the build. Say in the docs that it uses `TMPDIR`, so a caller that must keep credentials off disk knows to point `TMPDIR` at tmpfs.\n\nSpinbox side, for context: the plan covers secret scopes, delivery through tmpfs and FUSE, and prebuilds. It ships alongside devcontainer support.\n","author":{"url":"https://github.com/aledbf","@type":"Person","name":"aledbf"},"datePublished":"2026-11-07T16:53:19Z","url":"https://github.com/spin-stack/devcontainer-cli/issues/50"}
| react-profiling | 0 |
| react-import-map | react,react-dom,react-dom/client,react-dom/profiling,react-is,react-reconciler,react/compiler-runtime,react/jsx-dev-runtime,react/jsx-runtime,scheduler@d5750093facf |
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:b917ae02-49e0-af78-f242-bc6f675e31f0 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 9FDC:5C05F:5320B:75BBF:6AF6A83D |
| html-safe-nonce | 6369fbbc9f14a6b50c154fc1c1c8269ee25cadca5940c687c86788f2607a77c6 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5RkRDOjVDMDVGOjUzMjBCOjc1QkJGOjZBRjZBODNEIiwidmlzaXRvcl9pZCI6IjY4MDk0MjI0MDkwODI3NzU2MTMiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | c59c838cc3750827a653e90841c5d315e3e490024b6f226aaf9efc3f4d2bf6cb |
| hovercard-subject-tag | issue:6261771123 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/spin-stack/devcontainer-cli/50/issue_layout |
| twitter:image | https://opengraph.githubassets.com/3c076171c9d1ce47f74a6fe9b4924a71d2ea441335a1f43759a8dc0fdf09815d/spin-stack/devcontainer-cli/issues/50 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/3c076171c9d1ce47f74a6fe9b4924a71d2ea441335a1f43759a8dc0fdf09815d/spin-stack/devcontainer-cli/issues/50 |
| og:image:alt | Spinbox is adding devcontainer support and a new secrets model (installation → team → user scopes). Builds and containers run inside a workspace VM whose outbound traffic goes through an egress pro... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | aledbf |
| hostname | github.com |
| expected-hostname | github.com |
| None | f8f073848f247e43ef1ca770a5c958ec98a4831f252a2ae7c5728af8a418b119 |
| turbo-cache-control | no-preview |
| go-import | github.com/spin-stack/devcontainer-cli git https://github.com/spin-stack/devcontainer-cli.git |
| octolytics-dimension-user_id | 253817182 |
| octolytics-dimension-user_login | spin-stack |
| octolytics-dimension-repository_id | 1297553254 |
| octolytics-dimension-repository_nwo | spin-stack/devcontainer-cli |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 1297553254 |
| octolytics-dimension-repository_network_root_nwo | spin-stack/devcontainer-cli |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | d72fec342cb914fb2d289890ef4b2f15d229fe44 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
| react-app-name | issues |
Links:
Viewport: width=device-width