geni exec bash
Run a bash command locally with your connected credentials injected as environment variables by the cloud.
geni exec bash [flags] -- <command>Runs bash -lc <command> on your machine with one or more credentials' values injected as environment variables. The cloud resolves and decrypts them; the command runs locally; output is streamed back through a scrubber that redacts every secret. Use it for anything you would run in a shell: curl, git, gh, aws, language runtimes, ad-hoc scripts.
Synopsis
geni exec bash \
--cred cred_01HX --reason "Validating the Slack token" \
-- 'curl -s -H "Authorization: Bearer $SLACK_ACCESS_TOKEN_01HX" https://slack.com/api/auth.test'| Flag | Notes |
|---|---|
--cred <id> | Credential to inject. Repeat per credential; each --cred must be followed by exactly one --reason, paired by order. |
--reason <text> | Why this credential is being used. Lands in the workspace's credential access log and is shown to the operator. Required per credential. |
-f, --file <path> | Read the command from a file instead of after --. - reads from stdin. Preferred for anything with quotes or newlines. |
--cwd <path> | Working directory. Defaults to your current shell's. |
--quiet | Suppress the resolved <cred> → … status lines on stderr. Subprocess output still passes through, scrubbed. |
-- | Separator. Everything after it is the bash command. |
Env vars
Two flavors are set per credential:
- Suffixed,
$<SERVICE>_<FIELD>_<id>($SLACK_BOT_TOKEN_ABC,$SALESFORCE_INSTANCE_URL_KG). The suffix is the credential id withcred_stripped and uppercased, so two credentials of one service coexist in a single call. - Canonical aliases, the names SDKs hardcode (
$GH_TOKEN,$OPENAI_API_KEY,$STRIPE_API_KEY).
Read the exact names rather than deriving them:
geni credential get <id> --field envVars # for a known credential
geni integration get <service> --field envVars # for a serviceTwo more are always present, with no --cred required:
| Variable | Notes |
|---|---|
$PLATFORM_API_KEY | A short-lived bearer for General Input's own hosted services. |
$PLATFORM_BASE_URL | Their base URL. POST $PLATFORM_BASE_URL/search-internet, and so on. See hosted services. |
While a browser session is open, $GI_BROWSER_CDP_URL is exported too.
TLS trust is preconfigured (SSL_CERT_FILE, REQUESTS_CA_BUNDLE, CURL_CA_BUNDLE, GIT_SSL_CAINFO) so HTTPS from Python, curl, and git works without setup. Do not set them yourself.
What the subprocess inherits
Not your whole shell environment. The child starts from a small allowlist (PATH, HOME, USER, SHELL, PWD, locale, TERM, TMPDIR) plus the credential and platform variables. Anything else you exported is dropped, so a stale SLACK_BOT_TOKEN in your shell can never shadow the cloud-resolved one, and unrelated secrets never leak into the call.
Output
$ geni exec bash --cred cred_01HX --reason "…" -- 'curl -s https://api.example.com/'
{"data":[…]}stdout, stderr, and the exit code pass through as if you ran the command yourself. Any literal occurrence of a secret in the output is replaced with [REDACTED:credential_<id>], and common encodings are caught too.
Reasons are per call
Every --cred needs a --reason, on every invocation. The audit log is per call, not per session. Be specific ("Posting the daily digest to #engineering"), not generic ("Slack call").
Examples
One credential
geni exec bash \
--cred cred_01HX7AB --reason "Listing Salesforce contacts" \
-- 'curl -s -H "Authorization: Bearer $SALESFORCE_ACCESS_TOKEN_01HX7AB" "$SALESFORCE_INSTANCE_URL_01HX7AB/services/data/v59.0/sobjects/Contact"'Several credentials in one call
geni exec bash \
--cred cred_slackA --reason "Posting to #engineering" \
--cred cred_slackB --reason "Posting to #marketing" \
-- 'curl -s -X POST https://slack.com/api/chat.postMessage \
-H "Authorization: Bearer $SLACK_ACCESS_TOKEN_SLACKA" \
-d "channel=#engineering&text=hi"'A multi-line script (--file)
Fighting shell quoting through several layers is the most common way an exec bash call breaks. Write the script to a file and point --file at it; there are no quoting layers to escape:
cat > /tmp/q.sh <<'SCRIPT'
curl -s -H "Authorization: Bearer $QUICKBOOKS_ACCESS_TOKEN_01HX" \
"$QUICKBOOKS_BASE_URL/v3/company/$REALM/query?query=select%20*%20from%20Account" \
| jq '.QueryResponse.Account[] | {name: .Name, balance: .CurrentBalance}'
SCRIPT
geni exec bash --cred cred_01HX --reason "Reading QuickBooks accounts" --file /tmp/q.sh--file - reads the script from stdin, so a heredoc works directly. jq is available.
A hosted service, no credential
geni exec bash -- 'curl -s -X POST "$PLATFORM_BASE_URL/search-internet" \
-H "Authorization: Bearer $PLATFORM_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"query\":\"general input docs\"}"'Exit codes
| Code | Meaning |
|---|---|
0–125 | The subprocess's own exit code. |
77 | The server refused to resolve a credential. Do not retry; surface it. |
78 | The session is missing or expired. Run geni login. |
125 | Internal CLI error. |
A credential that resolved but produced an empty token (usually a failed OAuth refresh) is non-fatal: the call proceeds without it and the error prints to stderr, naming the credential to reconnect.