No-Call-Home Guarantee
The guarantee
Section titled “The guarantee”codegen makes zero outbound network requests during rule execution by default.
This is not a policy. It is enforced by the LuaU sandbox. There is no io library, no socket library, and no filesystem access of any kind — and none of those can be granted. The single escape hatch is http.get, which appears only when a rule’s config declares a host allowlist. A rule that attempts a network call without permission raises a runtime error and aborts the generation step for that entity.
Your source code, your AST, and your type information never leave your machine unless you write a rule that explicitly sends them somewhere, and approve that in config.
What the guarantee covers
Section titled “What the guarantee covers”The guarantee is about rule execution — what happens when codegen parses your headers and runs your rules. That path makes no outbound request, and the sandbox is what enforces it.
Two things sit outside that path and are network clients by design:
- The DTDK Manager, which installs, updates, and license-activates components. Nothing it does affects codegen’s runtime: once codegen is installed, running it executes rules with no network access.
codegen --browse-rules-registry, which fetches the public rules registry so you can install a rule. It runs only when you type that flag, it exits before any generation begins, and it never runs as part of a build.
Neither weakens the sentence above. Generation itself — the part that sees your AST — still makes zero outbound requests. If you never invoke the browser, codegen never opens a socket at all.
--browse-rules-registry talks to raw.githubusercontent.com and api.github.com, anonymously and without a token. Nothing about your code, your AST, or your machine is sent — the requests are plain reads of a public catalogue. A generation run (codegen -i … -a …) opens no sockets at all, which is straightforward to confirm with strace, dtruss, or Process Monitor.
Why this matters
Section titled “Why this matters”Code generation rules have privileged access. They receive the full parsed AST of your headers: every type, every field name, every annotation, every namespace. In a commercial codebase, this is sensitive intellectual property.
A rule distributed as part of a third-party library — a serialization framework, an RPC toolkit, a documentation generator — could, in a conventional system, exfiltrate this data. codegen’s sandbox closes that attack surface by default.
How the sandbox is implemented
Section titled “How the sandbox is implemented”The LuaU VM embedded in codegen starts with an empty global environment. The engine selectively injects the following globals before calling your rule:
| Global | Type | Description |
|---|---|---|
json.encode | function | Serialize a Lua value to a JSON string |
json.decode | function | Parse a JSON string to a Lua value |
AST-query natives (get_node, references, find_symbols, type_of, and others) | function | Read-only queries against the workspace daemon over a local Unix socket — how a rule receives your AST. Not a network call: the daemon is a process on your machine, not a remote endpoint. |
Alongside those, the VM opens a restricted subset of the Luau standard library — base, string, table, math, os, coroutine, utf8, bit32 — and then freezes the globals. Luau’s os is time-only (os.time, os.clock, os.date); it has no os.execute and no os.remove. There is no io, no require, no http, and no filesystem module of any kind.
The json globals are pure functions with no side effects and no I/O.
The permissions model
Section titled “The permissions model”Rules that legitimately need network access, fetching an OpenAPI spec, querying an internal schema registry, can request it explicitly in config.yaml:
version: 1
output: language: cpp
permissions: http: allowlist: - "schema-registry.internal.example.com" - "api.example.com"When this config is present, the engine injects an http.get(url) function into the sandbox. The function enforces the allowlist, any URL not on the list raises a runtime error.
Rules with HTTP permissions must be reviewed with the same scrutiny as any code that handles sensitive data. If you are using a third-party rule with an HTTP allowlist, verify that the allowlisted domains are legitimate before running.
The allowlist is mandatory. There is no permissions.http.allowAll flag. Every domain must be explicitly named. This is intentional: it prevents a rule from using a single high-entropy subdomain to exfiltrate data.
No license check
Section titled “No license check”codegen does not validate a license at startup. There is no local token, no signature check, and no entitlement gate of any kind — that whole code path, including the offline check it used to perform, has been removed from codegen entirely. There is nothing left in codegen that could contact a license service, even in principle.
Local logging
Section titled “Local logging”Each run writes a local structured log: the input path and rules directory, how many rules loaded, how many files were in scope, and how many files were written. Errors and warnings carry the rule, entity, and source path.
Logs are written to a local file only, under codegen’s own tool directory. They are never transmitted.
Supply chain attestation
Section titled “Supply chain attestation”See Supply Chain for provenance attestation, artifact signing, and reproducible build documentation.
- The no-call-home guarantee is enforced by the LuaU sandbox, not by policy. Rules cannot make network calls unless explicitly granted permission in config.
- The sandbox injects
json.encode/json.decodeplus read-only AST-query natives (local daemon IPC, not network), over a frozen subset of the Luau stdlib. Noio, norequire, nohttp, no filesystem — and Luau’sosis time-only. - HTTP permissions require an explicit domain allowlist. There is no allow-all flag.
- codegen has no license check at all — the old startup validation (and the network call it could make) has been removed entirely.
- Logs are written locally only, never transmitted.
--browse-rules-registryis the one network path in the tool. It is user-invoked, never part of a build, and reads a public catalogue anonymously.- For full provenance documentation, see the Supply Chain page.