All images, scripts and skills

Codex: sign in without a browser (auth)

sh

Drops a ready-made Codex login into a workspace so you do not have to authenticate in every new container. Supply it either way: **paste** the contents of `~/.codex/auth.json` from a machine where you are signed in, or **point at a file** — back a secret with `/home/dev/.codex/auth.json` in a workspace that is already signed in, and pick that secret. It is read fresh on every run, so a refreshed token reaches the next run without another paste. The value lands in `${CODEX_HOME:-~/.codex}/auth.json` (mode 600) and Codex is configured to use file-based credential storage. The old auth file is backed up to `auth.json.bak`; `jq` validates the JSON when available. **Security:** `auth.json` holds access tokens. It is collected as a secret and redacted from run logs. After it runs: start `codex` — it should come up already signed in.

What it asks for

Codex auth JSONrequired
The full contents of ~/.codex/auth.json from a machine where you are signed in — or a secret backed by that file in a workspace that is already signed in, which stays current without re-pasting. Redacted from run logs, and never persisted into the container environment profile.
Overwrite existing login
Choose 'no' to keep an auth.json already present in the container and only perform the remaining setup.

What it runs

The whole script, exactly as it will execute in your workspace. Nothing is hidden — read it before you run it.

#!/usr/bin/env sh
set -eu
umask 077

log()  { printf '[codex-setup] %s\n' "$*"; }
warn() { printf '[codex-setup] WARNING: %s\n' "$*" >&2; }
die()  { printf '[codex-setup] ERROR: %s\n' "$*" >&2; exit 1; }

AUTH_JSON="${CODEX_AUTH_JSON:-}"
OVERWRITE="${OVERWRITE_EXISTING_AUTH:-yes}"
CODEX_DIR="${CODEX_HOME:-$HOME/.codex}"
AUTH_FILE="$CODEX_DIR/auth.json"
CONFIG_FILE="$CODEX_DIR/config.toml"

[ -n "$AUTH_JSON" ] || die "no Codex auth JSON was supplied"
command -v codex >/dev/null 2>&1 \
    || die "the 'codex' CLI is not on PATH — run this in a workspace that has Codex installed"

if [ "$(id -u)" -eq 0 ]; then SUDO=""
elif command -v sudo >/dev/null 2>&1; then SUDO="sudo -n"
else SUDO=""
fi

# jq is optional: it validates the copied auth file. Never fail merely because
# jq cannot be installed; the login copy is still useful.
# This script body is piped to sh on stdin, so every installer gets </dev/null.
if ! command -v jq >/dev/null 2>&1; then
    log "jq not found; attempting install (optional)"
    export DEBIAN_FRONTEND=noninteractive
    if   command -v apt-get >/dev/null 2>&1; then $SUDO apt-get update -qq </dev/null && $SUDO apt-get install -y -qq jq </dev/null || true
    elif command -v dnf     >/dev/null 2>&1; then $SUDO dnf install -y jq </dev/null || true
    elif command -v yum     >/dev/null 2>&1; then $SUDO yum install -y jq </dev/null || true
    elif command -v apk     >/dev/null 2>&1; then $SUDO apk add --no-cache jq </dev/null || true
    elif command -v pacman  >/dev/null 2>&1; then $SUDO pacman -Sy --noconfirm jq </dev/null || true
    elif command -v zypper  >/dev/null 2>&1; then $SUDO zypper install -y jq </dev/null || true
    elif command -v brew    >/dev/null 2>&1; then brew install jq </dev/null || true
    fi
    command -v jq >/dev/null 2>&1 || warn "continuing without jq"
fi

mkdir -p "$CODEX_DIR"

if command -v jq >/dev/null 2>&1; then
    printf '%s' "$AUTH_JSON" | jq empty >/dev/null 2>&1 \
        || die "the supplied value is not valid JSON — paste the whole auth.json contents, from '{' to '}'"
fi

if [ -f "$AUTH_FILE" ] && [ "$OVERWRITE" != "yes" ]; then
    log "$AUTH_FILE already exists and overwrite is off — leaving it alone"
else
    if [ -f "$AUTH_FILE" ]; then
        cp -p "$AUTH_FILE" "$AUTH_FILE.bak"
        log "backed up previous credentials to $AUTH_FILE.bak"
    fi
    printf '%s\n' "$AUTH_JSON" > "$AUTH_FILE"
    chmod 600 "$AUTH_FILE"
    log "wrote $AUTH_FILE (mode 600)"
fi

# A copied auth.json must be selected explicitly when a credential store is
# available. Keep all unrelated Codex configuration intact.
if [ -f "$CONFIG_FILE" ]; then
    tmp="$CONFIG_FILE.devgrail.tmp"
    trap 'rm -f "$tmp"' 0
    if grep -Eq '^[[:space:]]*cli_auth_credentials_store[[:space:]]*=' "$CONFIG_FILE"; then
        sed 's/^[[:space:]]*cli_auth_credentials_store[[:space:]]*=.*$/cli_auth_credentials_store = "file"/' "$CONFIG_FILE" > "$tmp"
    else
        {
            printf '%s\n\n' 'cli_auth_credentials_store = "file"'
            cat "$CONFIG_FILE"
        } > "$tmp"
    fi
    if cmp -s "$CONFIG_FILE" "$tmp"; then
        rm -f "$tmp"
        trap - 0
        log "$CONFIG_FILE already selects file-based credential storage"
    else
        cp -p "$CONFIG_FILE" "$CONFIG_FILE.bak"
        mv "$tmp" "$CONFIG_FILE"
        trap - 0
        log "updated $CONFIG_FILE (backup: $CONFIG_FILE.bak)"
    fi
else
    printf '%s\n' 'cli_auth_credentials_store = "file"' > "$CONFIG_FILE"
    log "created $CONFIG_FILE"
fi
chmod 600 "$CONFIG_FILE"

log "done. Run 'codex' — it should start without asking you to log in."

How to get it

Open your DevGrail workspace, go to Scripts → Official scripts, and choose Download. It is copied into your own library, where you can edit it, run it, or set it as a workspace default — the copy is yours, and later changes here do not touch it.