Use runtime defaults when every machine created from a template should start in a specific directory or as a specific user.
builder = (
    Template()
    .from_python_image("3.12")
    .make_dir("/workspace/app")
    .copy("./app.py", "/workspace/app/app.py")
    .set_workdir("/workspace/app")
    .set_user("user")
    .set_runtime_envs({"APP_ENV": "production"})
)
const builder = client.templates
  .builder()
  .fromPythonImage("3.12")
  .makeDir("/workspace/app")
  .copy("./app.py", "/workspace/app/app.py")
  .setWorkdir("/workspace/app")
  .setUser("user")
  .setRuntimeEnvs({ APP_ENV: "production" });
nullspace template build \
  --from-python-image 3.12 \
  --make-dir /workspace/app \
  --copy-src ./app.py --copy-dst /workspace/app/app.py \
  --set-workdir /workspace/app \
  --set-user user \
  --set-runtime-env APP_ENV=production \
  --name app-template
# Default user, workdir, and envs live under runtime_config. COPY needs an
# uploaded build_context, so the full body is large — see the API reference.
curl -N -X POST "${NULLSPACE_API_URL}/v1/templates/build" \
  -H "Authorization: Bearer ${NULLSPACE_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "app-template",
    "base_image": "python:3.12",
    "steps": [{"action": "make_dir", "path": "/workspace/app"}],
    "runtime_config": {
      "default_workdir": "/workspace/app",
      "default_user": "user",
      "default_envs": {"APP_ENV": "production"}
    }
  }'
set_workdir() and set_user() become defaults for machines launched from the template. Individual build steps can still specify their own user when needed:
builder = builder.run_cmd("python3 -m compileall /workspace/app", user="user")
builder.runCmd("python3 -m compileall /workspace/app", { user: "user" });
nullspace template build \
  --from-python-image 3.12 \
  --run-cmd "python3 -m compileall /workspace/app" --run-user user \
  --name app-template
# A run step accepts an optional per-step user. Builds stream over SSE.
curl -N -X POST "${NULLSPACE_API_URL}/v1/templates/build" \
  -H "Authorization: Bearer ${NULLSPACE_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "app-template",
    "base_image": "python:3.12",
    "steps": [{"action": "run", "command": "python3 -m compileall /workspace/app", "user": "user"}]
  }'
Build-time environment variables are separate from runtime defaults:
builder = builder.set_build_envs({
    "PIP_INDEX_URL": "https://example.invalid/simple",
})
builder.setBuildEnvs({ PIP_INDEX_URL: "https://example.invalid/simple" });
nullspace template build \
  --from-python-image 3.12 \
  --set-build-env PIP_INDEX_URL=https://example.invalid/simple \
  --name app-template
# build_envs is a top-level object available only during the build.
curl -N -X POST "${NULLSPACE_API_URL}/v1/templates/build" \
  -H "Authorization: Bearer ${NULLSPACE_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "app-template",
    "base_image": "python:3.12",
    "build_envs": {"PIP_INDEX_URL": "https://example.invalid/simple"}
  }'