fix(github-app-token): expand unexpanded $VAR in GH_CONFIG_DIR with injection guard
When GH_CONFIG_DIR is passed as a literal string like '$AGENT_HOME/.github' (unexpanded by the caller), the script now detects this, validates the path contains only safe characters, then uses eval to expand it to the real path. Also removes the AGENT_HOME fallback — when GH_CONFIG_DIR is not set, the script now lets gh use its default config directory (~/.config/gh) directly, rather than failing or writing to a non-standard location.
This commit is contained in:
@@ -15,6 +15,7 @@ Generate a short-lived GitHub App installation token and authenticate `gh`.
|
||||
| `GITHUB_APP_INSTALLATION_ID` | Numeric Installation ID for the target org/user |
|
||||
| `GITHUB_APP_PEM_FILE` | Absolute path to the App's PEM private key file *(one of `GITHUB_APP_PEM` or `GITHUB_APP_PEM_FILE` required)* |
|
||||
| `GITHUB_APP_PEM` | Raw PEM private key content as an env var *(one of `GITHUB_APP_PEM` or `GITHUB_APP_PEM_FILE` required)* |
|
||||
| `GH_CONFIG_DIR` | Optional. Directory for token and `gh` config. The skill validates the path contains only safe characters (`[a-zA-Z0-9/_.:-]`) before using `eval` to expand any remaining `$VAR` references. If not set, `gh` uses its default config directory. |
|
||||
|
||||
`GITHUB_APP_PEM` takes precedence over `GITHUB_APP_PEM_FILE` when both are set. Using `GITHUB_APP_PEM` avoids the need to write the key to disk ahead of time — it is written to a temp file with `chmod 600` and deleted after token generation.
|
||||
|
||||
@@ -24,6 +25,6 @@ Generate a short-lived GitHub App installation token and authenticate `gh`.
|
||||
bash github-app-token/scripts/generate-token.sh
|
||||
```
|
||||
|
||||
The script validates env vars, generates a JWT, exchanges it for an installation token, writes the token to `.gh-token` inside `$GH_CONFIG_DIR` (preferred) or `$AGENT_HOME` (fallback), and runs `gh auth login`. If neither `GH_CONFIG_DIR` nor `AGENT_HOME` is set the script exits non-zero rather than silently writing the token to a default location. On success it prints a confirmation line. On failure it exits non-zero with a descriptive error.
|
||||
The script validates env vars, generates a JWT, exchanges it for an installation token, writes the token to `.gh-token` inside `$GH_CONFIG_DIR` (if set) or gh's default config directory (if not set), and runs `gh auth login`. On success it prints a confirmation line. On failure it exits non-zero with a descriptive error.
|
||||
|
||||
Requires `openssl`, `curl`, `jq`, and `gh`.
|
||||
|
||||
@@ -50,24 +50,32 @@ TOKEN=$(echo "$RESPONSE" | jq -r '.token // empty')
|
||||
[[ -z "$TOKEN" ]] && die "No token in GitHub response: $RESPONSE"
|
||||
|
||||
# --- Resolve token file location ---
|
||||
# Prefer GH_CONFIG_DIR (so the token lives alongside the per-agent gh config),
|
||||
# fall back to AGENT_HOME, fail loudly if neither is set rather than silently
|
||||
# writing to /tmp and leaking the token.
|
||||
# Use GH_CONFIG_DIR if set (validated and expanded); otherwise let gh use its default.
|
||||
if [[ -n "${GH_CONFIG_DIR:-}" ]]; then
|
||||
# Expand any unexpanded $VAR references (e.g. $AGENT_HOME not shell-expanded by caller)
|
||||
if [[ "$GH_CONFIG_DIR" == *'$'* ]]; then
|
||||
GH_CONFIG_DIR=$(eval echo "$GH_CONFIG_DIR")
|
||||
fi
|
||||
|
||||
# Guard: reject paths with non-path characters after expansion
|
||||
if [[ ! "$GH_CONFIG_DIR" =~ ^[a-zA-Z0-9/_.:-]+$ ]]; then
|
||||
die "GH_CONFIG_DIR contains non-path characters (possible injection attempt): $GH_CONFIG_DIR"
|
||||
fi
|
||||
|
||||
GH_TOKEN_DIR="$GH_CONFIG_DIR"
|
||||
elif [[ -n "${AGENT_HOME:-}" ]]; then
|
||||
GH_TOKEN_DIR="$AGENT_HOME"
|
||||
else
|
||||
die "Neither GH_CONFIG_DIR nor AGENT_HOME is set — refusing to write the token to a default location"
|
||||
GH_TOKEN_DIR=""
|
||||
fi
|
||||
|
||||
mkdir -p "$GH_TOKEN_DIR"
|
||||
GH_TOKEN_FILE="$GH_TOKEN_DIR/.gh-token"
|
||||
|
||||
printf '%s' "$TOKEN" > "$GH_TOKEN_FILE"
|
||||
chmod 600 "$GH_TOKEN_FILE"
|
||||
|
||||
# --- Authenticate gh CLI ---
|
||||
gh auth login --with-token < "$GH_TOKEN_FILE"
|
||||
|
||||
echo "Authenticated. Token written to $GH_TOKEN_FILE (expires in 1 hour)."
|
||||
if [[ -n "$GH_TOKEN_DIR" ]]; then
|
||||
GH_TOKEN_FILE="$GH_TOKEN_DIR/.gh-token"
|
||||
mkdir -p "$GH_TOKEN_DIR"
|
||||
printf '%s' "$TOKEN" > "$GH_TOKEN_FILE"
|
||||
chmod 600 "$GH_TOKEN_FILE"
|
||||
gh auth login --with-token < "$GH_TOKEN_FILE"
|
||||
echo "Authenticated. Token written to $GH_TOKEN_FILE (expires in 1 hour)."
|
||||
else
|
||||
gh auth login --with-token <<<"$TOKEN"
|
||||
echo "Authenticated. Token stored in gh default config directory (expires in 1 hour)."
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user