Query¶
The query command runs a jq expression against JSON produced by an idsec command — read from a file (for example output saved with --output-path) or from standard input. The expression is evaluated in-process using gojq, so the jq binary does not need to be installed.
This is the standalone counterpart to the inline --query flag available on commands such as exec: instead of querying a command's live output, query filters JSON you already have — from a saved file or piped in.
Run¶
# Save a command's output, then query it later
idsec exec cmgr pools list --output-path pools.json
idsec query --path pools.json --query '.[] | select(.type == "ACCESS") | .name'
# Or pipe JSON in without ever writing it to disk
idsec exec cmgr pools list | idsec query --query '.[] | select(.type == "ACCESS") | .name'
Options¶
--path— path to a JSON file produced by an idsec command. Use-, or omit--pathentirely, to read JSON from stdin. Reading from stdin keeps secret-bearing JSON off disk.--query(required) — the jq expression to evaluate against the JSON content.-n,--null-input— do not read any input; run the query againstnull, likejq -n. Use this to construct JSON purely from--arg/--argjsonbindings.--arg <name>=<value>— bind the stringvalueto the jq variable$name. Repeatable.--argjson <name>=<json>— bind the parsed JSONjsonto the jq variable$name. Repeatable.--raw— print a top-level string result unquoted, likejq -r(this common flag also disables colored output). Objects, arrays, numbers, and booleans are always rendered as JSON.
Constructing JSON with no input (-n)¶
Use -n when you want to build a JSON object from shell values rather than filter existing JSON — for example, a planner emitting a plan object or a resolver assembling a result. No file or stdin is read:
# Build a result object from bound values, no input needed
idsec query -n \
--query '{safe: $s, account: $a, rotated: $r}' \
--arg s="$SAFE_NAME" \
--arg a="$ACCOUNT_NAME" \
--argjson r=true
Passing shell values safely (--arg / --argjson)¶
Never interpolate a shell value into the query string — a value such as a safe, role, or pool name is user-supplied, and a name like x") | .credentials, (" would rewrite the expression (jq-program injection). Instead, bind the value to a variable and reference it with $name:
# Safe: the name is data, not program. Even hostile names can't alter the query.
SAFE_NAME='Prod DB'
idsec query --path safes.json \
--query '.[] | select(.safeName == $n) | .safeUrlId' \
--arg n="$SAFE_NAME"
# --argjson binds a JSON value (number, bool, object, array)
idsec query --path pools.json --query '.[] | select(.size > $min)' --argjson min=10
Unlike jq, each binding is a single name=value token (not two separate arguments). The value is split on the first =, so later = characters are preserved. The variable name must be a valid identifier ([A-Za-z_][A-Za-z0-9_]*).
Reading the environment (env / $ENV)¶
As in jq, the process environment is reachable through the env function and the $ENV variable, so an expression can resolve a value the caller places in the environment. This is useful for secrets: environment is a safer channel than argv, which is world-readable via ps for the process's lifetime.
# Resolve a secret whose variable name is named in the input (env[$v])
export DB_PASSWORD='s3cr3t'
echo '{"password_from_env":"DB_PASSWORD"}' \
| idsec query --raw --query '.password_from_env as $v | env[$v]'
# JSON-encode a raw secret without it ever reaching argv (jq -Rs . equivalent)
export SECRET_VALUE='a"b'
idsec query -n --query 'env.SECRET_VALUE' # → "a\"b"
Because query expressions are constants written by the caller and any user-supplied values are --arg-bound rather than interpolated, exposing the environment carries no injection risk here.
Notes¶
Multiple output values (for example from .[]) are each printed on their own line. A missing key follows jq semantics — .pool_id yields null, so use .pool_id // "" when capturing a scalar into a shell variable:
# Capture a single value, unquoted, with a safe fallback
POOL_ID=$(idsec query --path pool.json --raw --query '.pool_id // ""')
The command exits non-zero when the input cannot be read, its contents are not valid JSON, a variable binding is malformed, or the query expression is invalid or fails, so scripts can branch on the exit code.
Usage¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |