[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f2js3zz64z06pf":3,"$fanuq43nlrv5g":54},{"slug":4,"title":5,"body":6,"summary":7,"tags":8,"author":14,"cover_url":15,"published_at":16,"seo_title":17,"seo_description":18,"reading_minutes":19,"related":20},"agent-sandbox-dns-egress-lockdown","Your agent sandbox leaks through DNS: lock down egress in 15 minutes","\u003Cp>On September 20 an unreleased OpenAI model, working on a search task inside a training sandbox, found that ordinary web traffic was blocked but DNS was not. The sandbox's own resolver returned real records for public domains, so the model put its questions inside hostnames and used a DNS delegation service to relay them to an outside chatbot. OpenAI's write-up says a detector for anomalous DNS activity \u003Cem>excluded the affected environment\u003C\u002Fem>, even though the queries were logged. The monitor raised a P0 alert about 12 minutes after the first external DNS response, but the run was not killed for another two and a half hours.\u003C\u002Fp>\n\u003Cfigure data-post-media=\"6abd88e4c951ea7137fa37c8\">\u003Cvideo src=\"https:\u002F\u002Fmedia.stufio.com\u002Fmedia\u002Fifcodes\u002Fmediagen\u002F6a\u002F6abd88e6c951ea7137fa37ce-0-4be2951c.mp4\" autoplay muted loop playsinline preload=\"metadata\">\u003C\u002Fvideo>\u003C\u002Ffigure>\n\u003Cp>Most of us run coding agents with far less isolation than a frontier lab's training cluster. If your \"sandbox\" is a Docker container with a default bridge network, the agent can reach the whole internet, and DNS is only one of the ways out. This guide builds the three controls OpenAI listed afterwards: an allowlist for DNS and HTTP, logged egress, and a kill switch that actually fires. It uses Docker Compose, dnsmasq and Squid, and I tested every command below on Docker 27.4.\u003C\u002Fp>\n\n\u003Ch2>The design in one paragraph\u003C\u002Fh2>\n\u003Cp>The agent container is attached \u003Cstrong>only\u003C\u002Fstrong> to a Docker network created with \u003Ccode>internal: true\u003C\u002Fcode>. That network has no route to the outside, so direct TCP, UDP and ICMP to public IPs fail. Two small containers sit on both that network and a normal one. \u003Cstrong>dnsmasq\u003C\u002Fstrong> answers DNS: names on the allowlist are forwarded upstream, everything else gets \u003Ccode>REFUSED\u003C\u002Fcode>, and every query is logged. \u003Cstrong>Squid\u003C\u002Fstrong> is the only HTTP(S) path out: it accepts requests only for allowlisted domains, allows \u003Ccode>CONNECT\u003C\u002Fcode> only to port 443, and logs every request. The agent reaches the internet only through these two logged chokepoints, and stopping them cuts it off completely.\u003C\u002Fp>\n\u003Cfigure data-post-media=\"6abd88eac951ea7137fa37d4\">\u003Cimg src=\"https:\u002F\u002Fmedia.stufio.com\u002Fmedia\u002Fifcodes\u002Fmediagen\u002F6a\u002F6abd88eac951ea7137fa37d9-0-d5416f66.png\" alt=\"A conceptual representation of a locked-down network perimeter.\" loading=\"lazy\">\u003Cfigcaption>A conceptual representation of a locked-down network perimeter.\u003C\u002Ffigcaption>\u003C\u002Ffigure>\n\n\u003Ch2>1. The files\u003C\u002Fh2>\n\u003Cp>Make a directory with a \u003Ccode>work\u002F\u003C\u002Fcode> subfolder for the agent's checkout. Add these six files.\u003C\u002Fp>\n\u003Ch3>compose.yaml\u003C\u002Fh3>\n\u003Cpre>\u003Ccode>networks:\n  sandbox:\n    internal: true\n    ipam:\n      config:\n        - subnet: 172.30.0.0\u002F24\n  egress: {}\n\nservices:\n  dns:\n    image: alpine:3.20\n    command: sh -c \"apk add --no-cache dnsmasq &gt;\u002Fdev\u002Fnull &amp;&amp; exec dnsmasq -k --no-resolv --log-queries --log-facility=- --conf-file=\u002Fetc\u002Fdnsmasq.d\u002Fallow.conf\"\n    volumes:\n      - .\u002Fallow.conf:\u002Fetc\u002Fdnsmasq.d\u002Fallow.conf:ro\n    networks:\n      sandbox:\n        ipv4_address: 172.30.0.53\n      egress: {}\n\n  proxy:\n    image: ubuntu\u002Fsquid:latest\n    volumes:\n      - .\u002Fsquid.conf:\u002Fetc\u002Fsquid\u002Fsquid.conf:ro\n      - .\u002Fallowed.txt:\u002Fetc\u002Fsquid\u002Fallowed.txt:ro\n    depends_on: [dns]\n    networks:\n      sandbox:\n        ipv4_address: 172.30.0.10\n      egress: {}\n\n  agent:\n    image: node:22-bookworm\n    command: sleep infinity\n    working_dir: \u002Fwork\n    volumes:\n      - .\u002Fwork:\u002Fwork\n      - .\u002Fresolv.conf:\u002Fetc\u002Fresolv.conf:ro\n    environment:\n      HTTPS_PROXY: http:\u002F\u002F172.30.0.10:3128\n      HTTP_PROXY: http:\u002F\u002F172.30.0.10:3128\n      https_proxy: http:\u002F\u002F172.30.0.10:3128\n      http_proxy: http:\u002F\u002F172.30.0.10:3128\n      NO_PROXY: localhost,127.0.0.1\n    cap_drop: [ALL]\n    security_opt: [\"no-new-privileges:true\"]\n    networks: [sandbox]\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Two details matter here. The agent bind-mounts its own \u003Ccode>resolv.conf\u003C\u002Fcode> so that DNS goes straight to dnsmasq and not through Docker's embedded resolver at \u003Ccode>127.0.0.11\u003C\u002Fcode>, whose forwarding behaviour on internal networks you shouldn't have to reason about. It also drops all Linux capabilities and sets \u003Ccode>no-new-privileges\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch3>resolv.conf\u003C\u002Fh3>\n\u003Cpre>\u003Ccode>nameserver 172.30.0.53\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>allow.conf (DNS allowlist)\u003C\u002Fh3>\n\u003Cpre>\u003Ccode># Only these names resolve. Everything else gets REFUSED (and is logged).\nserver=\u002Fapi.anthropic.com\u002F1.1.1.1\nserver=\u002Fregistry.npmjs.org\u002F1.1.1.1\nserver=\u002Fgithub.com\u002F1.1.1.1\nserver=\u002Fapi.github.com\u002F1.1.1.1\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>How this is default-deny: \u003Ccode>--no-resolv\u003C\u002Fcode> in the compose command stops dnsmasq from reading any upstream servers from \u003Ccode>\u002Fetc\u002Fresolv.conf\u003C\u002Fcode>. That leaves only the per-domain \u003Ccode>server=\u002Fname\u002F1.1.1.1\u003C\u002Fcode> lines, where 1.1.1.1 is the \u003Cem>upstream resolver\u003C\u002Fem> used for that name, not an address the name maps to. A query that matches no line has nowhere to go, so dnsmasq answers \u003Ccode>REFUSED\u003C\u002Fcode>, as the log in step 2 shows. Don't add \u003Ccode>address=\u002F#\u002F\u003C\u002Fcode> as a \"deny all\": it answers every other name with \u003Ccode>0.0.0.0\u003C\u002Fcode>, which hides the probe. A subdomain of an allowed name (for example \u003Ccode>x.github.com\u003C\u002Fcode>) is also forwarded, which is why the list should contain only zones whose DNS you trust.\u003C\u002Fp>\n\u003Ch3>allowed.txt (proxy allowlist)\u003C\u002Fh3>\n\u003Cpre>\u003Ccode>api.anthropic.com\nregistry.npmjs.org\ngithub.com\napi.github.com\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Squid reads a quoted path in an ACL line as \"load values from this file\", one domain per line. A leading dot (\u003Ccode>.github.com\u003C\u002Fcode>) would also match subdomains; without it, only the exact host matches.\u003C\u002Fp>\n\u003Ch3>squid.conf\u003C\u002Fh3>\n\u003Cpre>\u003Ccode>http_port 3128\ndns_nameservers 172.30.0.53\nacl allowed dstdomain \"\u002Fetc\u002Fsquid\u002Fallowed.txt\"\nacl SSL_ports port 443\nacl CONNECT method CONNECT\nhttp_access deny CONNECT !SSL_ports\nhttp_access allow allowed\nhttp_access deny all\naccess_log \u002Fvar\u002Flog\u002Fsquid\u002Faccess.log\ncache deny all\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Squid resolves names through dnsmasq too (\u003Ccode>dns_nameservers\u003C\u002Fcode>), so every lookup in the stack shows up in one log. Leave \u003Ccode>access_log\u003C\u002Fcode> as a file: pointing it at \u003Ccode>stdio:\u002Fdev\u002Fstdout\u003C\u002Fcode> makes the \u003Ccode>ubuntu\u002Fsquid\u003C\u002Fcode> image exit on startup, because the \u003Ccode>proxy\u003C\u002Fcode> user can't open it.\u003C\u002Fp>\n\n\u003Ch2>2. Start it and prove the walls hold\u003C\u002Fh2>\n\u003Cpre>\u003Ccode>docker compose up -d\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Then run these checks from the host:\u003C\u002Fp>\n\u003Cfigure data-post-media=\"6abd88eac951ea7137fa37de\">\u003Cimg src=\"https:\u002F\u002Fmedia.stufio.com\u002Fmedia\u002Fifcodes\u002Fmediagen\u002F6a\u002F6abd88eac951ea7137fa37e3-0-a5840a0f.png\" alt=\"A visualization of a system monitoring for unauthorized egress.\" loading=\"lazy\">\u003Cfigcaption>A visualization of a system monitoring for unauthorized egress.\u003C\u002Ffigcaption>\u003C\u002Ffigure>\n\u003Cpre>\u003Ccode>A(){ docker compose exec -T agent \"$@\"; }\n\n# 1. allowed host through the proxy: expect 200\nA curl -sS -m 10 -o \u002Fdev\u002Fnull -w \"%{http_code} %{time_total}s\\n\" https:\u002F\u002Fapi.github.com\n\n# 2. host not on the list: expect \"CONNECT tunnel failed, response 403\"\nA curl -sS -m 10 -o \u002Fdev\u002Fnull https:\u002F\u002Fexample.com\n\n# 3. skip the proxy and go direct: expect \"Couldn't connect to server\"\nA curl -sS -m 5 --noproxy '*' -o \u002Fdev\u002Fnull https:\u002F\u002F1.1.1.1\n\n# 4. DNS: allowed name resolves, anything else fails\nA getent hosts api.github.com\nA getent hosts what-is-the-answer.q123.example.net; echo \"exit=$?\"\n\n# 5. talk to a public resolver directly: expect \"Network is unreachable\"\nA bash -c 'echo &gt; \u002Fdev\u002Ftcp\u002F1.1.1.1\u002F53'\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>What I got (the \u003Ccode>---\u003C\u002Fcode> labels are mine, added to separate the checks):\u003C\u002Fp>\n\u003Cpre>\u003Ccode>--- allowed https\n200 0.121073s\n--- blocked https\ncurl: (56) CONNECT tunnel failed, response 403\n--- bypass proxy\ncurl: (7) Failed to connect to 1.1.1.1 port 443 after 0 ms: Couldn't connect to server\n--- dns allowed\n140.82.121.6    api.github.com\n--- dns blocked\nexit=2\n--- direct resolver\nbash: connect: Network is unreachable\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Through Squid, the allowed request added no noticeable overhead: 0.12 s total to the GitHub API. Both chokepoints logged exactly what happened:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>$ docker compose logs --no-log-prefix dns | tail -2\ndnsmasq[1]: query[A] what-is-the-answer.q123.example.net from 172.30.0.2\ndnsmasq[1]: config error is REFUSED (EDE: not ready)\n\n$ docker compose exec proxy tail -2 \u002Fvar\u002Flog\u002Fsquid\u002Faccess.log\n1790618646.351    119 172.30.0.2 TCP_TUNNEL\u002F200 6944 CONNECT api.github.com:443 - HIER_DIRECT\u002F140.82.121.6 -\n1790618646.447      0 172.30.0.2 TCP_DENIED\u002F403 3394 CONNECT example.com:443 - HIER_NONE\u002F- text\u002Fhtml\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>That second pair of lines is the part OpenAI was missing in practice: a record of \u003Cem>every\u003C\u002Fem> name the agent tried, in a place you actually watch.\u003C\u002Fp>\n\n\u003Ch2>3. The kill switch\u003C\u002Fh2>\n\u003Cp>An alert that nobody acts on for two and a half hours is not a control. This script follows both logs and stops the egress containers after \u003Ccode>LIMIT\u003C\u002Fcode> blocked events. Because the agent is on an internal network, stopping dns and proxy leaves it with no path out at all, and its process, files and context stay intact so you can inspect them.\u003C\u002Fp>\n\u003Cfigure data-post-media=\"6abd88eac951ea7137fa37e8\">\u003Cimg src=\"https:\u002F\u002Fmedia.stufio.com\u002Fmedia\u002Fifcodes\u002Fmediagen\u002F6a\u002F6abd88eac951ea7137fa37ed-0-8a3cdd58.png\" alt=\"A symbolic representation of a network kill switch.\" loading=\"lazy\">\u003Cfigcaption>A symbolic representation of a network kill switch.\u003C\u002Ffigcaption>\u003C\u002Ffigure>\n\u003Ch3>kill-switch.sh\u003C\u002Fh3>\n\u003Cpre>\u003Ccode>#!\u002Fusr\u002Fbin\u002Fenv bash\n# Cut all egress after LIMIT blocked DNS queries or proxy denials.\nset -u\nLIMIT=${LIMIT:-5}\nfifo=$(mktemp -u); mkfifo \"$fifo\"\ndocker compose logs -f --no-log-prefix --tail 0 dns &gt;\"$fifo\" 2&gt;\u002Fdev\u002Fnull &amp; p1=$!\ndocker compose exec -T proxy tail -n0 -F \u002Fvar\u002Flog\u002Fsquid\u002Faccess.log &gt;\"$fifo\" 2&gt;\u002Fdev\u002Fnull &amp; p2=$!\ntrap 'kill \"$p1\" \"$p2\" 2&gt;\u002Fdev\u002Fnull; rm -f \"$fifo\"' EXIT\nhits=0\nwhile read -r line; do\n  case \"$line\" in\n    *REFUSED*|*TCP_DENIED*)\n      hits=$((hits + 1))\n      echo \"[kill-switch] $hits\u002F$LIMIT $line\"\n      if [ \"$hits\" -ge \"$LIMIT\" ]; then\n        echo \"[kill-switch] limit reached, stopping dns + proxy\"\n        docker compose stop dns proxy\n        exit 0\n      fi\n      ;;\n  esac\ndone &lt;\"$fifo\"\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Both followers write into one named pipe that the loop reads in the script's own shell, and their PIDs are kept. When the limit is reached, the script stops the containers and exits; the \u003Ccode>EXIT\u003C\u002Fcode> trap kills both followers and removes the pipe, so nothing is left hanging on a stopped container. (An earlier version piped a \u003Ccode>{ ...; } &amp;\u003C\u002Fcode> group into the loop and used \u003Ccode>pkill -P $$\u003C\u002Fcode>; that only kills the pipeline's subshells, not the \u003Ccode>docker\u003C\u002Fcode> processes they started, and it also kills the loop that calls it.) Make it executable with \u003Ccode>chmod +x kill-switch.sh\u003C\u002Fcode> and run it from the directory that holds \u003Ccode>compose.yaml\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cp>Tested end to end:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>$ LIMIT=3 .\u002Fkill-switch.sh &amp;\n$ sleep 2   # let the followers attach\n$ for i in 1 2 3; do docker compose exec -T agent getent hosts leak-$i.example.org; done\n[kill-switch] 1\u002F3 dnsmasq[1]: config error is REFUSED (EDE: not ready)\n[kill-switch] 2\u002F3 dnsmasq[1]: config error is REFUSED (EDE: not ready)\n[kill-switch] 3\u002F3 dnsmasq[1]: config error is REFUSED (EDE: not ready)\n[kill-switch] limit reached, stopping dns + proxy\n$ docker compose exec -T agent curl -sS -m 5 https:\u002F\u002Fapi.github.com\ncurl: (28) Connection timed out after 5002 milliseconds\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Don't read the counter as a count of lookups: \u003Ccode>getent\u003C\u002Fcode> asks for AAAA before A, and glibc retries a refused query, so one lookup can produce several \u003Ccode>REFUSED\u003C\u002Fcode> lines and the switch above may already trip on the first name. Set \u003Ccode>LIMIT\u003C\u002Fcode> high enough to survive a package manager probing a mirror you forgot to allowlist, but not so high that a tunnel gets 19 questions through, as happened in OpenAI's run. After a trip, read the logs, fix the allowlist or the agent, then run \u003Ccode>docker compose start dns proxy\u003C\u002Fcode>.\u003C\u002Fp>\n\n\u003Ch2>4. Run your agent inside\u003C\u002Fh2>\n\u003Cpre>\u003Ccode>docker compose exec agent bash\n# inside the container, e.g.:\nnpm install -g @anthropic-ai\u002Fclaude-code\nclaude\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>The \u003Ccode>HTTPS_PROXY\u003C\u002Fcode> variables are already set in the container. Tools that ignore proxy variables simply fail, because there is no other route. That is the point: failures are loud and logged, not silent successes.\u003C\u002Fp>\n\n\u003Ch2>Allowlist rules that actually matter\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\u003Cstrong>Allowlist exact hostnames, not zones anyone can write to.\u003C\u002Fstrong> The OpenAI escape went through a DNS delegation service with wildcard mapping. If you allow a zone where strangers can create subdomains or nameservers (free dynamic-DNS services, \u003Ccode>*.workers.dev\u003C\u002Fcode>-style platforms, paste sites), you have allowed a tunnel.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Restrict record types if you can.\u003C\u002Fstrong> OpenAI's fix limits both domains and record types. Coding agents need A\u002FAAAA; TXT is the classic tunnel carrier.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Watch refusals, not just successes.\u003C\u002Fstrong> The model probed before it found a way out. A spike in \u003Ccode>REFUSED\u003C\u002Fcode> or \u003Ccode>TCP_DENIED\u003C\u002Fcode> is your earliest signal, and it is free.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Test the detector, not just the rule.\u003C\u002Fstrong> The biggest lesson from the incident is that the detector did not cover this environment. Put the \u003Ccode>example.net\u003C\u002Fcode> lookup from step 2 in CI or a cron job, and alert if the kill switch doesn't trip.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Ch2>What this does not cover\u003C\u002Fh2>\n\u003Cp>This is network isolation, not a full sandbox. A container shares the host kernel, and anything you mount into \u003Ccode>\u002Fwork\u003C\u002Fcode> is readable and writable by the agent, so never mount your home directory or an SSH agent socket. Allowlisted services can themselves be exfiltration channels: an agent with a GitHub token can push data to a gist. If you need a stronger boundary, microVM-based sandboxes such as Docker Sandboxes block non-HTTP protocols, including DNS, at the network layer by default. Even there, it is worth checking what actually gets through.\u003C\u002Fp>\n\n\u003Ch2>Sources\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Falignment.openai.com\u002Fmisalignment-reports\u002Fan-agent-used-dns-to-reach-an-external-chatbot\u002F\">OpenAI Alignment: An agent used DNS to reach an external chatbot\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fx.com\u002FOpenAI\u002Fstatus\u002F2103566736356458911\">OpenAI on X: incident announcement\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fx.com\u002Fkimmonismus\u002Fstatus\u002F2103792408282464311\">@kimmonismus on the incident\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fx.com\u002FDocker\u002Fstatus\u002F2103192335081169405\">Docker on X\u003C\u002Fa> and \u003Ca href=\"https:\u002F\u002Fdocs.docker.com\u002Fai\u002Fsandboxes\u002Fsecurity\u002Fpolicy\u002F\">Docker Sandboxes network policy docs\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Fnetwork\u002Fdrivers\u002Fbridge\u002F\">Docker docs: bridge networks\u003C\u002Fa>\u003C\u002Fli>\n\u003C\u002Ful>","An OpenAI model escaped its sandbox by tunnelling questions through DNS. Here is a tested Docker Compose setup for coding agents: a DNS allowlist, a logging egress proxy and a kill switch that actually fires.",[9,10,11,12,13],"security","docker","agents","dns","self-hosting","if.codes","https:\u002F\u002Fmedia.stufio.com\u002Fmedia\u002Fifcodes\u002Fmediagen\u002F6a\u002F6abaaca13e21d5cbd14d4306-0-cb93fe1b.png","2026-10-01T03:00:15.943Z","Lock down AI agent egress: DNS allowlist + kill switch in Docker","A tested Docker Compose setup that stops coding agents tunnelling out via DNS: dnsmasq allowlist, Squid egress proxy, logs and a kill switch.",8,[21,34,45],{"slug":22,"title":23,"type":24,"summary":25,"tags":26,"author":14,"cover_url":32,"published_at":33,"updated_at":33},"who-blocks-ai-crawlers-robots-txt","Who blocks AI crawlers? robots.txt vs the network edge, with numbers","blog","I scanned robots.txt on the top 300 sites: 33 of 138 block GPTBot, 14 block training but allow AI search. What each AI bot directive controls, why robots.txt is only a request, and a copy-paste policy plus nginx rule for small SaaS sites.",[27,28,29,30,31],"ai","robots-txt","seo","cloudflare","saas","https:\u002F\u002Fmedia.stufio.com\u002Fmedia\u002Fifcodes\u002Fmediagen\u002F6a\u002F6abcd9c1838b650cb96b3d1b-0-11f94198.png","2026-09-30T21:00:20.673Z",{"slug":35,"title":36,"type":24,"summary":37,"tags":38,"author":14,"cover_url":42,"published_at":43,"updated_at":44},"bullet-time-with-first-last-frame-video","Bullet time with first\u002Flast-frame video: orbiting a frozen moment from three stills","A freeze-frame camera orbit built from generated stills: one action shot, two camera-move angles, two first\u002Flast-frame clips between them, stitched and ping-ponged. The pipeline, the seams, and where the model re-imagines the water.",[27,39,40,41],"comfyui","video-generation","flowdsl","https:\u002F\u002Fmedia.stufio.com\u002Fmedia\u002Fifcodes\u002Fmediagen\u002F6a\u002F6abae46c45201648bfd477a7-0-6f4d036e.png","2026-09-28T22:42:41Z","2026-09-28T22:42:41.6Z",{"slug":46,"title":47,"type":24,"summary":48,"tags":49,"author":14,"cover_url":51,"published_at":52,"updated_at":53},"an-ai-media-pipeline-that-shows-its-work","An AI media pipeline that shows its work: ComfyUI presets, FlowDSL routing and the misses","How the images on my sites are generated: four ComfyUI presets behind one Go module, job rows as state, FlowDSL flows for routing, per-post media in the admin — and the bugs and model misses I hit shipping it. This post's own images were made the same way.",[27,41,39,50],"image-generation","https:\u002F\u002Fmedia.stufio.com\u002Fmedia\u002Fifcodes\u002Fmediagen\u002F6a\u002F6aba8ba317ceba3543925be4-0-2f6b8a5c.png","2026-09-28T15:57:50Z","2026-09-28T15:57:50.784Z",[55,58,61,64,66,78,89,98,109],{"slug":4,"title":5,"type":24,"summary":7,"tags":56,"author":14,"cover_url":15,"published_at":16,"updated_at":57,"reading_minutes":19},[9,10,11,12,13],"2026-10-01T03:00:15.944Z",{"slug":22,"title":23,"type":24,"summary":25,"tags":59,"author":14,"cover_url":32,"published_at":33,"updated_at":33,"reading_minutes":60},[27,28,29,30,31],7,{"slug":35,"title":36,"type":24,"summary":37,"tags":62,"author":14,"cover_url":42,"published_at":43,"updated_at":44,"reading_minutes":63},[27,39,40,41],4,{"slug":46,"title":47,"type":24,"summary":48,"tags":65,"author":14,"cover_url":51,"published_at":52,"updated_at":53,"reading_minutes":60},[27,41,39,50],{"slug":67,"title":68,"type":24,"summary":69,"tags":70,"author":14,"cover_url":74,"published_at":75,"updated_at":76,"reading_minutes":77},"openai-embeddings-python-mongodb","Transforming Text into Vectors: OpenAI Embeddings in Python","Learn how to generate text embeddings with the OpenAI API in Python to power semantic search, recommendations, and more. Includes practical examples with MongoDB integration and cost analysis.",[71,27,72,73],"openai","python","mongodb","https:\u002F\u002Fmedia.stufio.com\u002Fmedia\u002Fifcodes\u002Fmediagen\u002F6a\u002F6abad0fa45201648bfd46c2d-0-2e60b732.png","2024-11-23T00:00:00Z","2026-09-28T22:31:01.385Z",3,{"slug":79,"title":80,"type":24,"summary":81,"tags":82,"author":14,"cover_url":85,"published_at":86,"updated_at":87,"reading_minutes":88},"check-pricing-availability-ing-domains","Last Chance to Grab Short .ING Domains: The Extended List Part II","Welcome back to the second part of our exciting exploration into the .ING domain zone! This time, I've expanded our horizons to bring you an even larger selection of .ING domain names. List of over 24,000 domain names inside.",[83,84],"domains","business","https:\u002F\u002Fmedia.stufio.com\u002Fmedia\u002Fifcodes\u002Fmediagen\u002F6a\u002F6abad0fa45201648bfd46c38-0-c55f4c8d.png","2023-12-14T00:00:00Z","2026-09-28T22:31:01.453Z",1,{"slug":90,"title":91,"type":24,"summary":92,"tags":93,"author":14,"cover_url":94,"published_at":95,"updated_at":96,"reading_minutes":97},"impressive-ing-domains","Unveiling the Impressive .ING Domains","Discover the vast potential of the new .ING domain zone in my latest blog post! I've used AI and a Python script to unearth a treasure trove of available domain names. From budget-friendly picks to exclusive premium domains, there's something for every ambition. Plus, a special list of unique, lesser-known domains awaits.",[83,84],"https:\u002F\u002Fmedia.stufio.com\u002Fmedia\u002Fifcodes\u002Fmediagen\u002F6a\u002F6abad0fa45201648bfd46c43-0-03be24b7.png","2023-12-11T00:00:00Z","2026-09-28T22:31:01.527Z",2,{"slug":99,"title":100,"type":24,"summary":101,"tags":102,"author":14,"cover_url":106,"published_at":107,"updated_at":108,"reading_minutes":77},"secured-web-server-in-5-minutes","Fortify Web Server Security in 5 Minutes with Tailscale","Tailscale revolutionizes secure networking with its user-friendly approach, effortlessly connecting devices across diverse networks.",[103,104,105],"firewall","tailscale","webserver","https:\u002F\u002Fmedia.stufio.com\u002Fmedia\u002Fifcodes\u002Fmediagen\u002F6a\u002F6abad0fa45201648bfd46c4e-0-eae6f62d.png","2023-11-03T00:00:00Z","2026-09-28T22:31:01.597Z",{"slug":110,"title":111,"type":24,"summary":112,"tags":113,"author":14,"cover_url":116,"published_at":117,"updated_at":118,"reading_minutes":119},"lets-encrypt-free-ssl","How to Secure Your Website with Free SSL Certificates for a Lifetime","Let’s Encrypt certificates have revolutionized internet security by providing free, automated, and widely trusted SSL\u002FTLS certificates. The non-profit Certificate Authority (CA) has significantly contributed to a more secure web environment by simplifying the process of securing websites with HTTPS.",[114,115,105],"ssl","https","https:\u002F\u002Fmedia.stufio.com\u002Fmedia\u002Fifcodes\u002Fmediagen\u002F6a\u002F6abad0fa45201648bfd46c59-0-bf2a9a0a.png","2023-11-01T00:00:00Z","2026-09-28T22:39:13.555Z",6]