Share Codex auth preflight
This commit is contained in:
285
bin/codex-auth-common.zsh
Normal file
285
bin/codex-auth-common.zsh
Normal file
@@ -0,0 +1,285 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
if [[ -n "${CODEX_AUTH_COMMON_LOADED:-}" ]]; then
|
||||
return 0
|
||||
fi
|
||||
CODEX_AUTH_COMMON_LOADED=1
|
||||
|
||||
CODEX_MCP_ENV_FILE="${CODEX_MCP_ENV_FILE:-${HOME}/.codex/mcp.env}"
|
||||
MCPGW_SELECTED_SERVERS_FILE="${MCPGW_SELECTED_SERVERS_FILE:-${HOME}/.ora-gateway/selected-servers.json}"
|
||||
MCPGW_OP_TOKEN_FILE="${MCPGW_OP_TOKEN_FILE:-${HOME}/.ora-gateway/op-token}"
|
||||
CODEX_DEVOPS_AUTH_SCRIPT="${CODEX_DEVOPS_AUTH_SCRIPT:-${HOME}/bin/codex-devops-auth.sh}"
|
||||
OCI_AUTH_CALLBACK_PORT="${OCI_AUTH_CALLBACK_PORT:-8181}"
|
||||
CODEX_AUTH_COMMON_AUTH_ENV_FILE=""
|
||||
CODEX_AUTH_COMMON_DEDICATED_AGENT_PID=""
|
||||
CODEX_AUTH_COMMON_DEDICATED_AGENT_SOCK=""
|
||||
|
||||
codex_auth_log() {
|
||||
print -u2 -- "$@"
|
||||
}
|
||||
|
||||
codex_auth_cleanup() {
|
||||
if [[ -n "${CODEX_AUTH_COMMON_DEDICATED_AGENT_PID}" && -n "${CODEX_AUTH_COMMON_DEDICATED_AGENT_SOCK}" ]]; then
|
||||
SSH_AGENT_PID="${CODEX_AUTH_COMMON_DEDICATED_AGENT_PID}" SSH_AUTH_SOCK="${CODEX_AUTH_COMMON_DEDICATED_AGENT_SOCK}" ssh-agent -k >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
if [[ -n "${CODEX_AUTH_COMMON_AUTH_ENV_FILE}" ]]; then
|
||||
rm -f "${CODEX_AUTH_COMMON_AUTH_ENV_FILE}" >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
codex_auth_sanitize_mcpgw_output() {
|
||||
local line clean redacted
|
||||
|
||||
while IFS= read -r line || [[ -n "${line}" ]]; do
|
||||
clean="$(printf '%s\n' "${line}" | perl -pe 's/\e\]8;;.*?\a//g; s/\e\[[0-?]*[ -\/]*[@-~]//g')"
|
||||
redacted="$(printf '%s\n' "${clean}" | sed -E \
|
||||
-e 's#https?://[^[:space:]]+#[redacted URL]#g' \
|
||||
-e 's#([Aa][Cc][Cc][Ee][Ss][Ss]_[Tt][Oo][Kk][Ee][Nn]=)[^[:space:]]+#\1[redacted]#g' \
|
||||
-e 's#([Ii][Dd]_[Tt][Oo][Kk][Ee][Nn]=)[^[:space:]]+#\1[redacted]#g' \
|
||||
-e 's#([Rr][Ee][Ff][Rr][Ee][Ss][Hh]_[Tt][Oo][Kk][Ee][Nn]=)[^[:space:]]+#\1[redacted]#g' \
|
||||
-e 's#([Ss][Ee][Cc][Uu][Rr][Ii][Tt][Yy]_[Tt][Oo][Kk][Ee][Nn]=)[^[:space:]]+#\1[redacted]#g' \
|
||||
-e 's#([Cc][Ll][Ii][Ee][Nn][Tt]_[Ss][Ee][Cc][Rr][Ee][Tt]=)[^[:space:]]+#\1[redacted]#g' \
|
||||
-e 's#([Pp][Uu][Bb][Ll][Ii][Cc]_[Kk][Ee][Yy]=)[^[:space:]]+#\1[redacted]#g' \
|
||||
-e 's#([Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]:[[:space:]]*).*#\1[redacted]#g' \
|
||||
-e 's#([Cc][Oo][Oo][Kk][Ii][Ee]:[[:space:]]*).*#\1[redacted]#g' \
|
||||
-e 's#([Ss][Ee][Tt]-[Cc][Oo][Oo][Kk][Ii][Ee]:[[:space:]]*).*#\1[redacted]#g' \
|
||||
-e 's#([^[:space:]]*/)?[.]oci/config#[redacted OCI config path]#g' \
|
||||
-e 's#(Config written to: ).*#\1[redacted config path]#')"
|
||||
|
||||
codex_auth_log "${redacted}"
|
||||
done
|
||||
}
|
||||
|
||||
codex_auth_is_truthy() {
|
||||
case "${1:-}" in
|
||||
1|true|TRUE|yes|YES|on|ON)
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
codex_auth_confluence_selected() {
|
||||
local selected_servers_file="${MCPGW_SELECTED_SERVERS_FILE}"
|
||||
|
||||
if [[ -r "${selected_servers_file}" ]] && LC_ALL=C grep -Eiq '"(Confluence|CentralConfluence|central_confluence|central-confluence)"' "${selected_servers_file}"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
case ",${CODEX_MCP_SERVERS:-}," in
|
||||
*,Confluence,*|*,confluence,*|*,CentralConfluence,*|*,central_confluence,*|*,central-confluence,*)
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
codex_auth_should_refresh_confluence_cookies() {
|
||||
if codex_auth_is_truthy "${CODEX_MCP_REFRESH_COOKIES:-}" || \
|
||||
codex_auth_is_truthy "${CODEX_MCP_REFRESH_CONFLUENCE_COOKIES:-}" || \
|
||||
codex_auth_is_truthy "${MCPGW_REFRESH_COOKIES:-}" || \
|
||||
codex_auth_is_truthy "${CODEX_MCP_CONFLUENCE_COOKIES_STALE:-}" || \
|
||||
codex_auth_is_truthy "${MCPGW_CONFLUENCE_COOKIES_STALE:-}"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
codex_auth_confluence_selected
|
||||
}
|
||||
|
||||
codex_auth_terminate_stale_oci_auth_listener() {
|
||||
local port="${1:-${OCI_AUTH_CALLBACK_PORT}}" pid cmd attempt
|
||||
local -a terminated_pids=()
|
||||
|
||||
if ! command -v lsof >/dev/null 2>&1 || ! command -v ps >/dev/null 2>&1; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
while IFS= read -r pid || [[ -n "${pid}" ]]; do
|
||||
[[ -n "${pid}" ]] || continue
|
||||
|
||||
cmd="$(ps -p "${pid}" -o command= 2>/dev/null || true)"
|
||||
if [[ "${cmd}" == *"oci session authenticate"* ]]; then
|
||||
codex_auth_log "MCP Gateway auth preflight: terminating stale OCI session authenticate listener on port ${port} (pid ${pid})."
|
||||
kill "${pid}" >/dev/null 2>&1 || true
|
||||
terminated_pids+=("${pid}")
|
||||
fi
|
||||
done < <(lsof -nP -t -iTCP:"${port}" -sTCP:LISTEN 2>/dev/null || true)
|
||||
|
||||
if [[ ${#terminated_pids[@]} -eq 0 ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
for pid in "${terminated_pids[@]}"; do
|
||||
for attempt in {1..10}; do
|
||||
if ! kill -0 "${pid}" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 0.2
|
||||
done
|
||||
|
||||
if kill -0 "${pid}" >/dev/null 2>&1; then
|
||||
codex_auth_log "MCP Gateway auth preflight: OCI auth listener pid ${pid} did not exit; sending SIGKILL."
|
||||
kill -KILL "${pid}" >/dev/null 2>&1 || true
|
||||
fi
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
codex_auth_run_mcpgw_required() {
|
||||
local mcpgw_bin="$1"
|
||||
shift
|
||||
local output rc
|
||||
|
||||
codex_auth_log "MCP Gateway auth preflight: mcpgw $*"
|
||||
|
||||
set +e
|
||||
output="$("${mcpgw_bin}" "$@" 2>&1)"
|
||||
rc=$?
|
||||
set -e
|
||||
printf '%s\n' "${output}" | codex_auth_sanitize_mcpgw_output
|
||||
|
||||
if [[ ${rc} -ne 0 && "$*" == "refresh" && "${output}" == *"port ${OCI_AUTH_CALLBACK_PORT} is already in use"* ]]; then
|
||||
if codex_auth_terminate_stale_oci_auth_listener "${OCI_AUTH_CALLBACK_PORT}"; then
|
||||
codex_auth_log "MCP Gateway auth preflight: retrying mcpgw refresh after clearing stale OCI auth listener."
|
||||
|
||||
set +e
|
||||
output="$("${mcpgw_bin}" "$@" 2>&1)"
|
||||
rc=$?
|
||||
set -e
|
||||
printf '%s\n' "${output}" | codex_auth_sanitize_mcpgw_output
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ${rc} -ne 0 ]]; then
|
||||
codex_auth_log "MCP Gateway auth preflight failed: mcpgw $* exited with ${rc}."
|
||||
exit "${rc}"
|
||||
fi
|
||||
}
|
||||
|
||||
codex_auth_prepare_codex_auth() {
|
||||
if [[ ! -x "${CODEX_DEVOPS_AUTH_SCRIPT}" ]]; then
|
||||
codex_auth_log "Warning: Codex DevOps auth helper not found or not executable: ${CODEX_DEVOPS_AUTH_SCRIPT}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! CODEX_AUTH_COMMON_AUTH_ENV_FILE="$(mktemp "${TMPDIR:-/tmp}/codex-devops-auth.XXXXXX")"; then
|
||||
codex_auth_log "Warning: could not create temporary Codex auth environment file."
|
||||
return 1
|
||||
fi
|
||||
|
||||
set +e
|
||||
CODEX_DEVOPS_AUTH_ENV_OUT="${CODEX_AUTH_COMMON_AUTH_ENV_FILE}" "${CODEX_DEVOPS_AUTH_SCRIPT}"
|
||||
local auth_rc=$?
|
||||
set -e
|
||||
|
||||
if [[ ${auth_rc} -ne 0 ]]; then
|
||||
codex_auth_log "Warning: Codex DevOps auth helper failed with exit code ${auth_rc}; could not refresh OP token."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ ! -s "${CODEX_AUTH_COMMON_AUTH_ENV_FILE}" ]]; then
|
||||
codex_auth_log "Warning: Codex DevOps auth helper did not write an auth environment; could not refresh OP token."
|
||||
return 1
|
||||
fi
|
||||
|
||||
set +e
|
||||
source "${CODEX_AUTH_COMMON_AUTH_ENV_FILE}"
|
||||
local source_rc=$?
|
||||
set -e
|
||||
|
||||
if [[ ${source_rc} -ne 0 ]]; then
|
||||
codex_auth_log "Warning: could not load Codex auth environment from ${CODEX_AUTH_COMMON_AUTH_ENV_FILE}; could not refresh OP token."
|
||||
return 1
|
||||
fi
|
||||
|
||||
CODEX_AUTH_COMMON_DEDICATED_AGENT_PID="${SSH_AGENT_PID:-}"
|
||||
CODEX_AUTH_COMMON_DEDICATED_AGENT_SOCK="${SSH_AUTH_SOCK:-}"
|
||||
}
|
||||
|
||||
codex_auth_write_gateway_op_token() {
|
||||
local token_file="${MCPGW_OP_TOKEN_FILE}"
|
||||
local token_dir tmp
|
||||
|
||||
if [[ -z "${OP_TOKEN:-}" ]]; then
|
||||
codex_auth_log "Warning: cannot write MCP Gateway OP token: OP_TOKEN is empty."
|
||||
return 1
|
||||
fi
|
||||
|
||||
token_dir="$(dirname -- "${token_file}")"
|
||||
if ! mkdir -p "${token_dir}"; then
|
||||
codex_auth_log "Warning: could not create MCP Gateway token directory: ${token_dir}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! tmp="$(mktemp "${token_file}.XXXXXX")"; then
|
||||
codex_auth_log "Warning: could not create temporary MCP Gateway OP token file for ${token_file}."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! printf '%s\n' "${OP_TOKEN}" > "${tmp}"; then
|
||||
codex_auth_log "Warning: could not write temporary MCP Gateway OP token file: ${tmp}"
|
||||
rm -f "${tmp}" >/dev/null 2>&1 || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! chmod 600 "${tmp}"; then
|
||||
codex_auth_log "Warning: could not set permissions on temporary MCP Gateway OP token file: ${tmp}"
|
||||
rm -f "${tmp}" >/dev/null 2>&1 || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! mv -f "${tmp}" "${token_file}"; then
|
||||
codex_auth_log "Warning: could not install MCP Gateway OP token file: ${token_file}"
|
||||
rm -f "${tmp}" >/dev/null 2>&1 || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
codex_auth_log "MCP Gateway auth preflight: wrote fresh operator token to ${token_file}."
|
||||
}
|
||||
|
||||
codex_auth_refresh_gateway_auth() {
|
||||
local mcpgw_bin op_token_refreshed=0
|
||||
mcpgw_bin="$(command -v mcpgw 2>/dev/null || true)"
|
||||
|
||||
if [[ -n "${mcpgw_bin}" ]]; then
|
||||
codex_auth_run_mcpgw_required "${mcpgw_bin}" refresh
|
||||
else
|
||||
codex_auth_log "Warning: mcpgw not found on PATH; skipping MCP Gateway auth refresh."
|
||||
fi
|
||||
|
||||
if codex_auth_prepare_codex_auth && codex_auth_write_gateway_op_token; then
|
||||
op_token_refreshed=1
|
||||
else
|
||||
codex_auth_log "Warning: could not refresh OP token; continuing with existing MCP Gateway token state."
|
||||
fi
|
||||
|
||||
if [[ -z "${mcpgw_bin}" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ "${op_token_refreshed}" != "1" ]]; then
|
||||
codex_auth_log "MCP Gateway auth preflight: skipping token-dependent checks because OP token refresh failed."
|
||||
return 0
|
||||
fi
|
||||
|
||||
if codex_auth_should_refresh_confluence_cookies; then
|
||||
codex_auth_run_mcpgw_required "${mcpgw_bin}" refresh-cookies
|
||||
else
|
||||
codex_auth_log "MCP Gateway auth preflight: skipping mcpgw refresh-cookies; Confluence auth was not requested."
|
||||
fi
|
||||
|
||||
codex_auth_run_mcpgw_required "${mcpgw_bin}" status
|
||||
}
|
||||
|
||||
codex_auth_preflight() {
|
||||
if [[ -r "${CODEX_MCP_ENV_FILE}" ]]; then
|
||||
source "${CODEX_MCP_ENV_FILE}"
|
||||
fi
|
||||
|
||||
codex_auth_refresh_gateway_auth
|
||||
}
|
||||
22
bin/codex-sso
Executable file
22
bin/codex-sso
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
export CODEX_HOME="${CODEX_HOME:-${HOME}/.codex-sso}"
|
||||
CODEX_AUTH_COMMON_SCRIPT="${CODEX_AUTH_COMMON_SCRIPT:-${HOME}/bin/codex-auth-common.zsh}"
|
||||
CODEX_BIN="${CODEX_BIN:-/opt/homebrew/bin/codex}"
|
||||
|
||||
if [[ ! -r "${CODEX_AUTH_COMMON_SCRIPT}" ]]; then
|
||||
print -u2 -- "Codex auth common helper not found or not readable: ${CODEX_AUTH_COMMON_SCRIPT}"
|
||||
exit 1
|
||||
fi
|
||||
source "${CODEX_AUTH_COMMON_SCRIPT}"
|
||||
|
||||
trap codex_auth_cleanup EXIT INT TERM
|
||||
|
||||
codex_auth_preflight
|
||||
|
||||
unset OPENAI_API_KEY
|
||||
unset CODEX_ACCESS_TOKEN
|
||||
|
||||
"${CODEX_BIN}" --disable guardian_approval -a untrusted "$@"
|
||||
@@ -2,65 +2,16 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
CODEX_MCP_ENV_FILE="${CODEX_MCP_ENV_FILE:-${HOME}/.codex/mcp.env}"
|
||||
MCPGW_SELECTED_SERVERS_FILE="${MCPGW_SELECTED_SERVERS_FILE:-${HOME}/.ora-gateway/selected-servers.json}"
|
||||
MCPGW_OP_TOKEN_FILE="${MCPGW_OP_TOKEN_FILE:-${HOME}/.ora-gateway/op-token}"
|
||||
CODEX_DEVOPS_AUTH_SCRIPT="${CODEX_DEVOPS_AUTH_SCRIPT:-${HOME}/bin/codex-devops-auth.sh}"
|
||||
CODEX_AUTH_COMMON_SCRIPT="${CODEX_AUTH_COMMON_SCRIPT:-${HOME}/bin/codex-auth-common.zsh}"
|
||||
CODEX_BIN="${CODEX_BIN:-/opt/homebrew/bin/codex}"
|
||||
CODEX_WRAPPER_CODEX_PROFILE="${CODEX_WRAPPER_CODEX_PROFILE:-}"
|
||||
CODEX_WRAPPER_DEFAULT_CODEX_PROFILE="${CODEX_WRAPPER_DEFAULT_CODEX_PROFILE:-gpt-5-5}"
|
||||
CODEX_WRAPPER_AUTH_ENV_FILE=""
|
||||
CODEX_WRAPPER_DEDICATED_AGENT_PID=""
|
||||
CODEX_WRAPPER_DEDICATED_AGENT_SOCK=""
|
||||
OCI_AUTH_CALLBACK_PORT="${OCI_AUTH_CALLBACK_PORT:-8181}"
|
||||
|
||||
log() {
|
||||
print -u2 -- "$@"
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
if [[ -n "${CODEX_WRAPPER_DEDICATED_AGENT_PID}" && -n "${CODEX_WRAPPER_DEDICATED_AGENT_SOCK}" ]]; then
|
||||
SSH_AGENT_PID="${CODEX_WRAPPER_DEDICATED_AGENT_PID}" SSH_AUTH_SOCK="${CODEX_WRAPPER_DEDICATED_AGENT_SOCK}" ssh-agent -k >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
if [[ -n "${CODEX_WRAPPER_AUTH_ENV_FILE}" ]]; then
|
||||
rm -f "${CODEX_WRAPPER_AUTH_ENV_FILE}" >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
sanitize_mcpgw_output() {
|
||||
local line clean redacted
|
||||
|
||||
while IFS= read -r line || [[ -n "${line}" ]]; do
|
||||
clean="$(printf '%s\n' "${line}" | perl -pe 's/\e\]8;;.*?\a//g; s/\e\[[0-?]*[ -\/]*[@-~]//g')"
|
||||
redacted="$(printf '%s\n' "${clean}" | sed -E \
|
||||
-e 's#https?://[^[:space:]]+#[redacted URL]#g' \
|
||||
-e 's#([Aa][Cc][Cc][Ee][Ss][Ss]_[Tt][Oo][Kk][Ee][Nn]=)[^[:space:]]+#\1[redacted]#g' \
|
||||
-e 's#([Ii][Dd]_[Tt][Oo][Kk][Ee][Nn]=)[^[:space:]]+#\1[redacted]#g' \
|
||||
-e 's#([Rr][Ee][Ff][Rr][Ee][Ss][Hh]_[Tt][Oo][Kk][Ee][Nn]=)[^[:space:]]+#\1[redacted]#g' \
|
||||
-e 's#([Ss][Ee][Cc][Uu][Rr][Ii][Tt][Yy]_[Tt][Oo][Kk][Ee][Nn]=)[^[:space:]]+#\1[redacted]#g' \
|
||||
-e 's#([Cc][Ll][Ii][Ee][Nn][Tt]_[Ss][Ee][Cc][Rr][Ee][Tt]=)[^[:space:]]+#\1[redacted]#g' \
|
||||
-e 's#([Pp][Uu][Bb][Ll][Ii][Cc]_[Kk][Ee][Yy]=)[^[:space:]]+#\1[redacted]#g' \
|
||||
-e 's#([Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]:[[:space:]]*).*#\1[redacted]#g' \
|
||||
-e 's#([Cc][Oo][Oo][Kk][Ii][Ee]:[[:space:]]*).*#\1[redacted]#g' \
|
||||
-e 's#([Ss][Ee][Tt]-[Cc][Oo][Oo][Kk][Ii][Ee]:[[:space:]]*).*#\1[redacted]#g' \
|
||||
-e 's#([^[:space:]]*/)?[.]oci/config#[redacted OCI config path]#g' \
|
||||
-e 's#(Config written to: ).*#\1[redacted config path]#')"
|
||||
|
||||
log "${redacted}"
|
||||
done
|
||||
}
|
||||
|
||||
is_truthy() {
|
||||
case "${1:-}" in
|
||||
1|true|TRUE|yes|YES|on|ON)
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
if [[ ! -r "${CODEX_AUTH_COMMON_SCRIPT}" ]]; then
|
||||
print -u2 -- "Codex auth common helper not found or not readable: ${CODEX_AUTH_COMMON_SCRIPT}"
|
||||
exit 1
|
||||
fi
|
||||
source "${CODEX_AUTH_COMMON_SCRIPT}"
|
||||
|
||||
codex_home() {
|
||||
print -r -- "${CODEX_HOME:-${HOME}/.codex}"
|
||||
@@ -115,230 +66,12 @@ codex_profile_flag() {
|
||||
print -r -- "--profile"
|
||||
}
|
||||
|
||||
confluence_selected() {
|
||||
local selected_servers_file="${MCPGW_SELECTED_SERVERS_FILE}"
|
||||
trap codex_auth_cleanup EXIT INT TERM
|
||||
|
||||
if [[ -r "${selected_servers_file}" ]] && LC_ALL=C grep -Eiq '"(Confluence|CentralConfluence|central_confluence|central-confluence)"' "${selected_servers_file}"; then
|
||||
return 0
|
||||
fi
|
||||
codex_auth_preflight
|
||||
|
||||
case ",${CODEX_MCP_SERVERS:-}," in
|
||||
*,Confluence,*|*,confluence,*|*,CentralConfluence,*|*,central_confluence,*|*,central-confluence,*)
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
should_refresh_confluence_cookies() {
|
||||
if is_truthy "${CODEX_MCP_REFRESH_COOKIES:-}" || \
|
||||
is_truthy "${CODEX_MCP_REFRESH_CONFLUENCE_COOKIES:-}" || \
|
||||
is_truthy "${MCPGW_REFRESH_COOKIES:-}" || \
|
||||
is_truthy "${CODEX_MCP_CONFLUENCE_COOKIES_STALE:-}" || \
|
||||
is_truthy "${MCPGW_CONFLUENCE_COOKIES_STALE:-}"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
confluence_selected
|
||||
}
|
||||
|
||||
terminate_stale_oci_auth_listener() {
|
||||
local port="${1:-${OCI_AUTH_CALLBACK_PORT}}" pid cmd attempt
|
||||
local -a terminated_pids=()
|
||||
|
||||
if ! command -v lsof >/dev/null 2>&1 || ! command -v ps >/dev/null 2>&1; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
while IFS= read -r pid || [[ -n "${pid}" ]]; do
|
||||
[[ -n "${pid}" ]] || continue
|
||||
|
||||
cmd="$(ps -p "${pid}" -o command= 2>/dev/null || true)"
|
||||
if [[ "${cmd}" == *"oci session authenticate"* ]]; then
|
||||
log "MCP Gateway auth preflight: terminating stale OCI session authenticate listener on port ${port} (pid ${pid})."
|
||||
kill "${pid}" >/dev/null 2>&1 || true
|
||||
terminated_pids+=("${pid}")
|
||||
fi
|
||||
done < <(lsof -nP -t -iTCP:"${port}" -sTCP:LISTEN 2>/dev/null || true)
|
||||
|
||||
if [[ ${#terminated_pids[@]} -eq 0 ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
for pid in "${terminated_pids[@]}"; do
|
||||
for attempt in {1..10}; do
|
||||
if ! kill -0 "${pid}" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 0.2
|
||||
done
|
||||
|
||||
if kill -0 "${pid}" >/dev/null 2>&1; then
|
||||
log "MCP Gateway auth preflight: OCI auth listener pid ${pid} did not exit; sending SIGKILL."
|
||||
kill -KILL "${pid}" >/dev/null 2>&1 || true
|
||||
fi
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
run_mcpgw_required() {
|
||||
local mcpgw_bin="$1"
|
||||
shift
|
||||
local output rc
|
||||
|
||||
log "MCP Gateway auth preflight: mcpgw $*"
|
||||
|
||||
set +e
|
||||
output="$("${mcpgw_bin}" "$@" 2>&1)"
|
||||
rc=$?
|
||||
set -e
|
||||
printf '%s\n' "${output}" | sanitize_mcpgw_output
|
||||
|
||||
if [[ ${rc} -ne 0 && "$*" == "refresh" && "${output}" == *"port ${OCI_AUTH_CALLBACK_PORT} is already in use"* ]]; then
|
||||
if terminate_stale_oci_auth_listener "${OCI_AUTH_CALLBACK_PORT}"; then
|
||||
log "MCP Gateway auth preflight: retrying mcpgw refresh after clearing stale OCI auth listener."
|
||||
|
||||
set +e
|
||||
output="$("${mcpgw_bin}" "$@" 2>&1)"
|
||||
rc=$?
|
||||
set -e
|
||||
printf '%s\n' "${output}" | sanitize_mcpgw_output
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ${rc} -ne 0 ]]; then
|
||||
log "MCP Gateway auth preflight failed: mcpgw $* exited with ${rc}."
|
||||
exit "${rc}"
|
||||
fi
|
||||
}
|
||||
|
||||
prepare_codex_auth() {
|
||||
if [[ ! -x "${CODEX_DEVOPS_AUTH_SCRIPT}" ]]; then
|
||||
log "Warning: Codex DevOps auth helper not found or not executable: ${CODEX_DEVOPS_AUTH_SCRIPT}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! CODEX_WRAPPER_AUTH_ENV_FILE="$(mktemp "${TMPDIR:-/tmp}/codex-devops-auth.XXXXXX")"; then
|
||||
log "Warning: could not create temporary Codex auth environment file."
|
||||
return 1
|
||||
fi
|
||||
|
||||
set +e
|
||||
CODEX_DEVOPS_AUTH_ENV_OUT="${CODEX_WRAPPER_AUTH_ENV_FILE}" "${CODEX_DEVOPS_AUTH_SCRIPT}"
|
||||
local auth_rc=$?
|
||||
set -e
|
||||
|
||||
if [[ ${auth_rc} -ne 0 ]]; then
|
||||
log "Warning: Codex DevOps auth helper failed with exit code ${auth_rc}; could not refresh OP token."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ ! -s "${CODEX_WRAPPER_AUTH_ENV_FILE}" ]]; then
|
||||
log "Warning: Codex DevOps auth helper did not write an auth environment; could not refresh OP token."
|
||||
return 1
|
||||
fi
|
||||
|
||||
set +e
|
||||
source "${CODEX_WRAPPER_AUTH_ENV_FILE}"
|
||||
local source_rc=$?
|
||||
set -e
|
||||
|
||||
if [[ ${source_rc} -ne 0 ]]; then
|
||||
log "Warning: could not load Codex auth environment from ${CODEX_WRAPPER_AUTH_ENV_FILE}; could not refresh OP token."
|
||||
return 1
|
||||
fi
|
||||
|
||||
CODEX_WRAPPER_DEDICATED_AGENT_PID="${SSH_AGENT_PID:-}"
|
||||
CODEX_WRAPPER_DEDICATED_AGENT_SOCK="${SSH_AUTH_SOCK:-}"
|
||||
}
|
||||
|
||||
write_gateway_op_token() {
|
||||
local token_file="${MCPGW_OP_TOKEN_FILE}"
|
||||
local token_dir tmp
|
||||
|
||||
if [[ -z "${OP_TOKEN:-}" ]]; then
|
||||
log "Warning: cannot write MCP Gateway OP token: OP_TOKEN is empty."
|
||||
return 1
|
||||
fi
|
||||
|
||||
token_dir="$(dirname -- "${token_file}")"
|
||||
if ! mkdir -p "${token_dir}"; then
|
||||
log "Warning: could not create MCP Gateway token directory: ${token_dir}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! tmp="$(mktemp "${token_file}.XXXXXX")"; then
|
||||
log "Warning: could not create temporary MCP Gateway OP token file for ${token_file}."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! printf '%s\n' "${OP_TOKEN}" > "${tmp}"; then
|
||||
log "Warning: could not write temporary MCP Gateway OP token file: ${tmp}"
|
||||
rm -f "${tmp}" >/dev/null 2>&1 || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! chmod 600 "${tmp}"; then
|
||||
log "Warning: could not set permissions on temporary MCP Gateway OP token file: ${tmp}"
|
||||
rm -f "${tmp}" >/dev/null 2>&1 || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! mv -f "${tmp}" "${token_file}"; then
|
||||
log "Warning: could not install MCP Gateway OP token file: ${token_file}"
|
||||
rm -f "${tmp}" >/dev/null 2>&1 || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
log "MCP Gateway auth preflight: wrote fresh operator token to ${token_file}."
|
||||
}
|
||||
|
||||
refresh_gateway_auth() {
|
||||
local mcpgw_bin op_token_refreshed=0
|
||||
mcpgw_bin="$(command -v mcpgw 2>/dev/null || true)"
|
||||
|
||||
if [[ -n "${mcpgw_bin}" ]]; then
|
||||
run_mcpgw_required "${mcpgw_bin}" refresh
|
||||
else
|
||||
log "Warning: mcpgw not found on PATH; skipping MCP Gateway auth refresh."
|
||||
fi
|
||||
|
||||
if prepare_codex_auth && write_gateway_op_token; then
|
||||
op_token_refreshed=1
|
||||
else
|
||||
log "Warning: could not refresh OP token; continuing with existing MCP Gateway token state."
|
||||
fi
|
||||
|
||||
if [[ -z "${mcpgw_bin}" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ "${op_token_refreshed}" != "1" ]]; then
|
||||
log "MCP Gateway auth preflight: skipping token-dependent checks because OP token refresh failed."
|
||||
return 0
|
||||
fi
|
||||
|
||||
if should_refresh_confluence_cookies; then
|
||||
run_mcpgw_required "${mcpgw_bin}" refresh-cookies
|
||||
else
|
||||
log "MCP Gateway auth preflight: skipping mcpgw refresh-cookies; Confluence auth was not requested."
|
||||
fi
|
||||
|
||||
run_mcpgw_required "${mcpgw_bin}" status
|
||||
}
|
||||
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
if [[ -r "${CODEX_MCP_ENV_FILE}" ]]; then
|
||||
source "${CODEX_MCP_ENV_FILE}"
|
||||
fi
|
||||
|
||||
refresh_gateway_auth
|
||||
|
||||
if is_truthy "${CODEX_WRAPPER_DRY_RUN:-}"; then
|
||||
log "CODEX_WRAPPER_DRY_RUN is set; skipping Codex launch."
|
||||
if codex_auth_is_truthy "${CODEX_WRAPPER_DRY_RUN:-}"; then
|
||||
codex_auth_log "CODEX_WRAPPER_DRY_RUN is set; skipping Codex launch."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user