Skip to content

Trust injected CA certificate on sandbox startup#550

Open
scuffi wants to merge 9 commits intomainfrom
load-runtime-intercept-ca-cert
Open

Trust injected CA certificate on sandbox startup#550
scuffi wants to merge 9 commits intomainfrom
load-runtime-intercept-ca-cert

Conversation

@scuffi
Copy link
Copy Markdown
Contributor

@scuffi scuffi commented Apr 1, 2026

Summary

To support HTTPS egress interception, we must trust an injected CA certificate into external requests. This PR adds a blocking loader to fetch & trust this certificate during container server startup. In production, this certificate will exist at startup, so there should be minimal overhead introduced. The polling/blocking mechanism is for local development to ensure parity as the certificate cannot be assumed to exist at startup due to Docker API limitations.

Request Support

We are doing a 'best-effort' approach here by populating commonly used CA certificate environment variables, however, this approach is always going to be limited by packages or processes that ignore common system CA certificates, which we won't be able to intercept.


Open with Devin

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 1, 2026

🦋 Changeset detected

Latest commit: bb24fd1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@cloudflare/sandbox Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 1, 2026

Open in StackBlitz

npm i https://pkg.pr.new/cloudflare/sandbox-sdk/@cloudflare/sandbox@550

commit: bb24fd1

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

🐳 Docker Images Published

Variant Image
Default cloudflare/sandbox:0.0.0-pr-550-bb24fd1
Python cloudflare/sandbox:0.0.0-pr-550-bb24fd1-python
OpenCode cloudflare/sandbox:0.0.0-pr-550-bb24fd1-opencode
Musl cloudflare/sandbox:0.0.0-pr-550-bb24fd1-musl
Desktop cloudflare/sandbox:0.0.0-pr-550-bb24fd1-desktop

Usage:

FROM cloudflare/sandbox:0.0.0-pr-550-bb24fd1

Version: 0.0.0-pr-550-bb24fd1


📦 Standalone Binary

For arbitrary Dockerfiles:

COPY --from=cloudflare/sandbox:0.0.0-pr-550-bb24fd1 /container-server/sandbox /sandbox
ENTRYPOINT ["/sandbox"]

Download via GitHub CLI:

gh run download 24091022254 -n sandbox-binary

Extract from Docker:

docker run --rm cloudflare/sandbox:0.0.0-pr-550-bb24fd1 cat /container-server/sandbox > sandbox && chmod +x sandbox

@scuffi
Copy link
Copy Markdown
Contributor Author

scuffi commented Apr 1, 2026

/bonk review this PR

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk bot commented Apr 1, 2026

UnknownError: ProviderInitError

github run

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk bot commented Apr 1, 2026

@scuffi Bonk workflow was cancelled.

View workflow run · To retry, trigger Bonk again.

@scuffi scuffi force-pushed the load-runtime-intercept-ca-cert branch from 57c223d to 441043a Compare April 1, 2026 16:59
@scuffi
Copy link
Copy Markdown
Contributor Author

scuffi commented Apr 1, 2026

/bonk review this PR

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk bot commented Apr 1, 2026

UnknownError: ProviderInitError

github run

@scuffi scuffi marked this pull request as ready for review April 1, 2026 23:55
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 4 additional findings.

Open in Devin Review


export async function trustRuntimeCert(): Promise<void> {
// Default to the Cloudflare containers injected CA certificate
const certPath =
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's be careful on polling this certificate. I really recommend the sandbox accepting a flag that enables the trustRuntimeCert call (the user is opting in to https intercept).
If the container runtime is not calling HTTPS interception this file is not created.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, in production polling is not necessary, if interceptOutboundHttps is called before the start() call, there is not a chance the file does not exist when the container runs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're only polling here to ensure parity between local & production. As I don't think we can check if we're in production or local development here, we run through the exists file check, which should immediately return true if we're in production as the file will always exist as you mention, however, may be slightly delayed in local development but still ensures parity as we block startup until the certificate is injected, wdyt?

@scuffi scuffi force-pushed the load-runtime-intercept-ca-cert branch from c3c515a to 982d49e Compare April 7, 2026 10:33
@scuffi
Copy link
Copy Markdown
Contributor Author

scuffi commented Apr 7, 2026

/bonk review this PR

devin-ai-integration[bot]

This comment was marked as resolved.

Copy link
Copy Markdown
Member

@ghostwriternr ghostwriternr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, thanks for adding a bunch of tests too! Have some minor comments

@scuffi
Copy link
Copy Markdown
Contributor Author

scuffi commented Apr 7, 2026

@ghostwriternr

@scuffi can we explore this just a bit more? So looking at the runtime, the cert is injected into the container when interceptOutboundHttps() calls injectCACert() from the runtime. And at least as per today's implementation, this is triggered by applyOutboundInterception() on the container class within blockConcurrencyWhile() in the constructor, which should be before any request reaches and gets handled by the container. So if I read this correctly, the cert should already exist by the time the container starts?

Yeah this is what I thought, however, I think this is only true for production and maybe Docker engine locally has some constraints? I've noticed in my testing approx ~200ms delay here when running locally which is why I've had to add the polling. The method does immediately check & return to minimise overhead in production, but I think if we want exact parity here we're going to need this polling due to local constraints

@ghostwriternr
Copy link
Copy Markdown
Member

Thanks for explaining, that makes sense! We can resolve that thread then

@scuffi scuffi force-pushed the load-runtime-intercept-ca-cert branch from 7643bdf to a81cc9d Compare April 7, 2026 15:28
@scuffi scuffi force-pushed the load-runtime-intercept-ca-cert branch from e59f91a to bb24fd1 Compare April 7, 2026 15:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants