Skip to content
Talk to our solutions team

What a script can reach

A script reaches atoms through namespacesshell.execute(), db.query(), s3.download(). Which namespaces exist is decided by the host, and at the CLI the default grant is everything.

To see the grant for yourself:

function main() {
const names = [];
for (const k in globalThis) names.push(k);
return names.sort();
}
Terminal window
kis script run globals.js --debug

That is worth running once in whatever context you care about, because the answer differs between the CLI, a flow’s script: task, and a script embedded in a service.

Some names are present no matter what, including under --namespaces none:

NamespaceFor
logLog lines
jsonParse and serialise
string, array, mathValue helpers
time, now, tsnanoClock and timestamps
uuid, ulid, nanoidIdentifier generation
hashDigests
template, interpolateString templating
cpetThe tenancy coordinate this script is running under

The unifying property: nothing here reaches outside the process. No filesystem, no network, no subprocess. They are language services, and removing them would leave a script unable to compute or report at all.

That is why --namespaces none is meaningful rather than absolute — it removes every namespace that can reach something.

With the default --namespaces all, roughly eighty names are bound. By what they touch:

GroupNamespaces
Local executionshell, supershell
Remote executionssh, scp, rsync
Filesfile, fs, glob, archive, extract
Structured textyaml, jq, liquid
Networkhttp, rest, dns
Databasesdb
Object storages3, azureblob
Secretsvault, secret, crypt, letsencrypt
Source controlgit
Containers and clustersdocker, podman, k8s, kubectl
Host and processport, cron, osuser, lock, wait
Identifiersid
AIllm, embed, rag, vector, milvus, intent, guard, reason, scrape, text, validate, pipeline
Data pipelinecsv, excel, parquet, entity, morph, aggregate, compute, stdout
Documentsocr
Authorizationuser, rbac, abac, ambient, ownership, fields, rls
Platformconfig, vars

Each is documented in the atom reference, alongside the flow task that reaches the same atom.

Two of these groups deserve a note. Authorization namespaces answer who is asking — they return zero values at the CLI, where there is no request identity, and are populated when a script runs inside a service. Data pipeline namespaces are most useful inside a pipeline, where the record stream is the point.

--namespaces takes all, none, or a list:

Terminal window
kis script run transform.js --namespaces none
kis script run fetch.js --namespaces http,json
kis script run deploy.js --namespaces shell,ssh,vault

The list is added to the base set, not substituted for it. --namespaces http gives a script http plus everything in the base set — so it can still compute, log and return, which is what makes the narrow grant usable at all.

$ kis script run globals.js --namespaces none --debug
Result: ["array","cpet","hash","interpolate","json","log","math","nanoid",
"now","string","template","time","tsnano","ulid","uuid", ...]
$ kis script run globals.js --namespaces shell --debug
Result: [... the same, plus "shell"]

A flow’s script: task takes the same parameter:

- name: transform
script:
language: javascript
file: ./transform.js
namespaces: json,string
setvar: cleaned

Name what the script needs. The list is short for most scripts, and writing it down is a one-line statement of intent that survives the script being edited later:

The scriptGrant
Transforms data it was handednone
Calls one API and reshapes the answerhttp
Reads a database and reportsdb
Deploys to hostsshell,ssh,vault
Is generated by a model, or came from outsidenone, and add only what it demonstrably needs

The last row is the one that matters. Code you did not write and cannot fully review should start at none and earn each addition. Pairing that with a language that contributes no authority of its own — Starlark — means the script’s reach is exactly the list you wrote, and nothing has to be audited to know it.

Restricting a grant is a design decision, so make it where the script is configured rather than at the point of running it. A flow that carries namespaces: in its definition keeps the constraint; a --namespaces flag typed at a terminal does not survive the next invocation.