Skip to content

Tutorial: masking and its limit

Goal

At the end you will see masking work on a value the API reflects back, and see exactly where it stops working.

Every command and output below comes from a real run, recorded in demo/tutorials/masking/expected/ and checked by run.sh --check.

Run it

bash demo/tutorials/masking/run.sh all
bash demo/tutorials/masking/run.sh --check

Script: demo/tutorials/masking/run.sh.

1. A reflected value is masked

The API puts the received header in its answer. The agent reads the reference, not the value.

# The API reflects the header back: the agent sees the reference, not the value

$ BAO_WRAPPING_TOKEN=<wrapped token> khcall keyholder_run '{"command":"curl","args":["-sS","-H","Authorization: Bearer {{vault://my-project/dev/API_TOKEN}}","http://127.0.0.1:18080/"]}'
{
  "exit_code": 0,
  "refs_used": [
    "vault://my-project/dev/API_TOKEN"
  ],
  "stderr": "",
  "stdout": "api says: hello, caller with header Authorization: Bearer [hidden:vault://my-project/dev/API_TOKEN]\n"
}
--- stderr
<timestamp> audit cmd="curl" refs=[vault://my-project/dev/API_TOKEN] exit=0 dur=<duration> status=ok
exit_code=0

Did the API receive the stored token? yes

stderr is masked the same way (covered by internal/runner tests).

2. LIMIT: encoding escapes the mask

python3 is allowed here only to show the limit. The interpreter base64-encodes the value and the agent reads it, unmasked. Masking only matches the exact value; this is why the allow list must never include interpreters or shells (sh, bash, python3, node, env).

# LIMIT: an allowed interpreter can encode the value and escape the mask

$ BAO_WRAPPING_TOKEN=<wrapped token> khcall keyholder_run '{"command":"python3","args":["-c","import base64,sys; print(base64.b64encode(sys.argv[1].encode()).decode())","{{vault://my-project/dev/API_TOKEN}}"]}'
{
  "exit_code": 0,
  "refs_used": [
    "vault://my-project/dev/API_TOKEN"
  ],
  "stderr": "",
  "stdout": "dG9rLWZha2Utbm90LWEtcmVhbC1zZWNyZXQ=\n"
}
--- stderr
<timestamp> audit cmd="python3" refs=[vault://my-project/dev/API_TOKEN] exit=0 dur=<duration> status=ok
exit_code=0

Decoded: tok-fake-not-a-real-secret (the fake token, unmasked)