{
  "id": 2124798,
  "title": "Taking the network away from a Cloud Run job",
  "url": "https://urgent.news/2026/08/20/taking-the-network-away-from-a-cloud-run-job",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-08-20T11:46:20.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/amartyadev/taking-the-network-away-from-a-cloud-run-job-3il7"
  },
  "original_language": "en",
  "account": "When you run someone else's code, you must determine what it is permitted to access. Mine should be limited to its own filesystem and loopback interface, with no external connections. The usual solutions involve managing your own Kubernetes cluster or using Firecracker directly, but these require additional operational overhead. Instead, I sought a managed solution where the platform handles container execution and notifies when it completes, without a network connection. Here's how to achieve this on Cloud Run, along with two details not mentioned in the documentation.\n\nA Cloud Run job runs the command you provide. To strip away the network, use the command 'unshare -rn -- ./run-the-untrusted-thing'. The '-r' flag is crucial as it creates a new network namespace, which includes only a loopback device and no routes to the outside world. Consequently, nothing within this namespace can interact with the external network.\n\nThis method works specifically with Cloud Run's second-generation execution environment, which utilizes a microVM with a real Linux kernel rather than gVisor's syscall-filtering layer. However, on the first-generation environment, such operations are unsupported and will fail. To resolve this, include a line of code that raises the loopback interface: import fcntl, socket, struct, os, sys; define a function to modify network flags; and execute it before running the user's code. This ten-line shim raises the loopback interface without introducing additional processes or altering the exit code of the actual command.\n\nLastly, remember that managed job runners retry failed executions by default. While this is appropriate for data pipelines, it can be problematic for applications where failures should be recorded as failures rather than successes. To prevent automatic retries, set maxRetries to 0. Isolating the code in a separate network namespace provides a strong boundary for security, assuming no kernel exploits are present. Remember, however, that this does not guarantee complete protection against sophisticated attacks and that the platform's resources are shared.",
  "summary": "If you execute other people's code, at some point you have to decide what it is allowed to reach. Mine should reach nothing: no package registry, no pastebin, no callback to a server that tells it the answer. It should see its own filesystem, its own loopback interface, and the end of the world in every other direction. The usual answers are all heavy. Run your own Kubernetes with a deny-all…",
  "key_points": [
    "Use unshare -rn -- ./run-the-untrusted-thing to strip network from Cloud Run job",
    "Works only with second-generation Cloud Run environment with microVM",
    "Set maxRetries to 0 to prevent automatic retries on failure"
  ],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}