fix(security-review): resolve Confluence cloudId via accessible-resources, not /_edge/tenant_info (#41)

The public /_edge/tenant_info endpoint returns an HTML 'Page Unavailable' on the
seahavenind site, so cloudId auto-resolution failed. Fetch the token first, then
resolve cloudId from the OAuth-native https://api.atlassian.com/oauth/token/
accessible-resources (Bearer), preferring the resource whose url matches the
configured site, else the first. CONFLUENCE_CLOUD_ID override still honored.
Canary 3/3 (offline), shellcheck clean.
This commit is contained in:
Adam Moussa 2026-06-22 19:47:38 -04:00 • committed by GitHub
parent 332652257b
commit 593f8c60b8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -221,15 +221,8 @@ _CONF_MODE=""; _CONF_BASE=""; _CONF_BEARER=""
conf_api_init() {
if [ -n "$CONFLUENCE_OAUTH_CLIENT_ID" ] && [ -n "$CONFLUENCE_OAUTH_CLIENT_SECRET" ]; then
local cid="$CONFLUENCE_CLOUD_ID"
if [ -z "$cid" ] && [ -n "$CONFLUENCE_BASE_URL" ]; then
cid="$(curl -sS -H 'Accept: application/json' \
"$CONFLUENCE_BASE_URL/_edge/tenant_info" 2>>"$REPORT_DIR/confluence-api.log" \
| jq -r '.cloudId // empty' 2>/dev/null)"
fi
[ -n "$cid" ] || { log "OAuth: could not resolve cloudId — skipping API"; return 1; }
# 2LO client-credentials token. The secret goes in the request BODY via
# --data-urlencode and is never echoed/logged (matches the existing -u risk class).
# 2LO client-credentials token FIRST (the secret goes in the request BODY via
# --data-urlencode and is never echoed/logged — matches the existing -u risk class).
local tok
tok="$(curl -sS -X POST "$CONFLUENCE_OAUTH_TOKEN_URL" \
-H 'Content-Type: application/x-www-form-urlencoded' \
@ -238,6 +231,18 @@ conf_api_init() {
--data-urlencode 'grant_type=client_credentials' \
2>>"$REPORT_DIR/confluence-api.log" | jq -r '.access_token // empty' 2>/dev/null)"
[ -n "$tok" ] || { log "OAuth: token request failed — skipping API (no false alarm)"; return 1; }
# Resolve the cloudId: use CONFLUENCE_CLOUD_ID if given, else the OAuth-native
# accessible-resources endpoint (the public /_edge/tenant_info is not reliable).
# Prefer the resource whose url matches the configured site; else the first.
local cid="$CONFLUENCE_CLOUD_ID"
if [ -z "$cid" ]; then
cid="$(curl -sS -H "Authorization: Bearer $tok" -H 'Accept: application/json' \
'https://api.atlassian.com/oauth/token/accessible-resources' \
2>>"$REPORT_DIR/confluence-api.log" \
| jq -r --arg url "$CONFLUENCE_BASE_URL" \
'(map(select(.url==$url)) | .[0].id) // .[0].id // empty' 2>/dev/null)"
fi
[ -n "$cid" ] || { log "OAuth: could not resolve cloudId (set CONFLUENCE_CLOUD_ID) — skipping API"; return 1; }
_CONF_MODE="oauth"; _CONF_BEARER="$tok"
_CONF_BASE="https://api.atlassian.com/ex/confluence/$cid"
return 0