Restrict what a script can reach
A script that can reach exactly the host capabilities it needs, and nothing else.
Why bother
Section titled “Why bother”By default a script can read files, make HTTP calls, query databases, reach secrets and run shell commands. That is right for a script you wrote and wrong for one you did not.
| Without this | With this |
|---|---|
| Every script can reach every capability | A script gets what its job needs |
| A generated script has the same reach as a reviewed one | Generated code runs constrained |
| A bug in a transform can make a network call | It cannot |
| ”What can this script do?” needs a code review | It is on the command line |
What is available
Section titled “What is available”With the default --namespaces all:
log http file db vault json time shell llmThat is a lot of reach — file, shell, db, vault and http are each enough to matter.
Restricting
Section titled “Restricting”kis script run transform.js --namespaces nonelog json timeOr name what you need:
kis script run fetch.js --namespaces log,http,jsonChoosing a set
Section titled “Choosing a set”| The script | Namespaces |
|---|---|
| Pure transformation | none |
| Calls an API | log,http,json |
| Reads or writes files | log,file,json |
| Queries data | log,db,json |
| Needs a secret | log,vault — and think hard about why |
| Generated or untrusted | Start at none and add only what it fails without |
That last row is the method: run it with none, see what it fails on, and grant that. What you end
up with is the actual requirement rather than a guess.
Put it where it survives
Section titled “Put it where it survives”A grant typed at a terminal protects one invocation. The grant that matters is the one in the definition, because that is the one that runs tomorrow.
- name: transform script: language: javascript file: ./transform.js namespaces: json,string setvar: cleanednamespaces: is the same grant as --namespaces, written where it is reviewed in a diff and
applied on every run. This is the form to reach for: a constraint in the definition is a constraint
someone has to consciously remove.
kis script run transform.js --namespaces json,stringRight for developing and for a one-off. Note what it is not: a property of the script. The next person to run the file gets whatever they type, which is why the flow form above is where the grant belongs once the work is real.
Verify
Section titled “Verify”Ask the script what it can see:
function main() { const seen = []; for (const n of ["log","http","file","db","vault","json","time","shell","llm"]) { if (typeof globalThis[n] !== "undefined") seen.push(n); } return seen;}kis script run probe.js --namespaces log,json --debugRun that with the flags you intend to use in production. It answers “what can this reach” directly rather than by inference.
Related
Section titled “Related”- Choose a language — Starlark constrains by construction
- Benchmark and set a timeout — bounding time as well as reach