11#! /bin/bash
22# =============================================================================
3- # ttyd Entrypoint Script
3+ # Sandbox Entrypoint Script
44# =============================================================================
55#
6- # Starts ttyd web terminal with HTTP Basic Auth enabled .
6+ # Sets up Codex configuration, starts code-server, and starts ttyd web terminal .
77#
88# Authentication Flow:
9- # 1. ttyd validates credentials at HTTP/WebSocket layer via -c parameter
10- # 2. URL format: ?authorization=base64(user:password)&arg=SESSION_ID
11- # 3. ttyd-startup.sh handles session tracking (not auth) for file upload cwd detection
9+ # ttyd-auth.sh receives the access token via ?arg=TOKEN and validates it
10+ # against the TTYD_ACCESS_TOKEN environment variable.
1211#
1312# Required Environment Variables:
14- # TTYD_ACCESS_TOKEN - Password for HTTP Basic Auth (username is 'user')
13+ # TTYD_ACCESS_TOKEN - Access token for terminal authentication
1514#
16- # Optional URL Parameters (via -a flag):
17- # arg=SESSION_ID - Terminal session ID for file upload directory tracking
15+ # Optional Environment Variables:
16+ # CODEX_API_KEY - API key for Codex (written to ~/.codex/auth.json)
17+ # CODEX_BASE_URL - LLM API base URL for Codex (written to ~/.codex/config.toml)
1818#
1919# =============================================================================
2020
2121set -euo pipefail
2222
23+ FULLING_USER=" ${FULLING_USER:- fulling} "
24+ FULLING_GROUP=" ${FULLING_GROUP:- fulling} "
25+ FULLING_HOME=" ${FULLING_HOME:-/ home/ fulling} "
26+ SKEL_DIR=" ${SKEL_DIR:-/ etc/ skel} "
27+ TTYD_AUTH_SCRIPT=" ${TTYD_AUTH_SCRIPT:-/ usr/ local/ bin/ ttyd-auth.sh} "
28+ FULLING_WORKSPACE=" ${FULLING_WORKSPACE:- $FULLING_HOME / next} "
29+ EDITOR_PASSWORD=" ${EDITOR_PASSWORD:- ${TTYD_ACCESS_TOKEN:- } } "
30+
31+ maybe_chown () {
32+ if [ " $( id -u) " -eq 0 ]; then
33+ chown " $@ "
34+ fi
35+ }
36+
37+ mkdir -p " $FULLING_HOME "
38+ mkdir -p " $FULLING_WORKSPACE "
39+ export HOME=" $FULLING_HOME "
40+ export USER=" $FULLING_USER "
41+ export LOGNAME=" $FULLING_USER "
42+ export CODEX_HOME=" ${CODEX_HOME:- $FULLING_HOME / .codex} "
43+
2344# -----------------------------------------------------------------------------
2445# Validate required environment variables
2546# -----------------------------------------------------------------------------
26- if [ -z " $TTYD_ACCESS_TOKEN " ]; then
47+ if [ -z " ${ TTYD_ACCESS_TOKEN:- } " ]; then
2748 echo " ERROR: TTYD_ACCESS_TOKEN environment variable is not set"
2849 echo " This is required for terminal authentication"
2950 exit 1
3051fi
3152
3253# -----------------------------------------------------------------------------
33- # Build HTTP Basic Auth credential
34- # Format: username:password (username is fixed as 'user')
54+ # Copy shell config files from skeleton to PVC-mounted home directory
55+ # On first run the PVC is empty, so .bashrc needs to be copied
3556# -----------------------------------------------------------------------------
36- TTYD_CREDENTIAL=" user:${TTYD_ACCESS_TOKEN} "
57+ for skelfile in .bashrc .tmux.conf; do
58+ if [ ! -f " $FULLING_HOME /$skelfile " ] && [ -f " $SKEL_DIR /$skelfile " ]; then
59+ cp " $SKEL_DIR /$skelfile " " $FULLING_HOME /$skelfile "
60+ maybe_chown " $FULLING_USER :$FULLING_GROUP " " $FULLING_HOME /$skelfile "
61+ fi
62+ done
63+
64+ # -----------------------------------------------------------------------------
65+ # Setup Codex configuration
66+ # Writes ~/.codex/config.toml and ~/.codex/auth.json from environment variables.
67+ # These are regenerated on every container start so settings changes take effect
68+ # after pod restart.
69+ # -----------------------------------------------------------------------------
70+ CODEX_CONFIG_DIR=" $CODEX_HOME "
71+ CODEX_CONFIG_FILE=" ${CODEX_CONFIG_DIR} /config.toml"
72+ CODEX_AUTH_FILE=" ${CODEX_CONFIG_DIR} /auth.json"
73+
74+ # Write config.toml if CODEX_BASE_URL is set
75+ if [ -n " ${CODEX_BASE_URL:- } " ]; then
76+ mkdir -p " $CODEX_CONFIG_DIR "
77+ cat > " $CODEX_CONFIG_FILE " << CODEX_CONFIG_EOF
78+ service_tier = "fast"
79+ model_provider = "litellm"
80+
81+ [model_providers.litellm]
82+ name = "OpenAI"
83+ base_url = "${CODEX_BASE_URL} "
84+ wire_api = "responses"
85+ requires_openai_auth = true
86+ CODEX_CONFIG_EOF
87+ maybe_chown " $FULLING_USER :$FULLING_GROUP " " $CODEX_CONFIG_FILE "
88+ echo " ✓ Codex config initialized (base_url: ${CODEX_BASE_URL} )"
89+ fi
90+
91+ # Write auth.json if CODEX_API_KEY is set
92+ if [ -n " ${CODEX_API_KEY:- } " ]; then
93+ mkdir -p " $CODEX_CONFIG_DIR "
94+ cat > " $CODEX_AUTH_FILE " << CODEX_AUTH_EOF
95+ {
96+ "auth_mode": "apikey",
97+ "OPENAI_API_KEY": "${CODEX_API_KEY} "
98+ }
99+ CODEX_AUTH_EOF
100+ maybe_chown " $FULLING_USER :$FULLING_GROUP " " $CODEX_AUTH_FILE "
101+ echo " ✓ Codex auth configured"
102+ fi
103+
104+ # Ensure proper ownership of codex config directory
105+ if [ -d " $CODEX_CONFIG_DIR " ]; then
106+ maybe_chown -R " $FULLING_USER :$FULLING_GROUP " " $CODEX_CONFIG_DIR " 2> /dev/null || true
107+ fi
37108
38109# -----------------------------------------------------------------------------
39110# Terminal theme configuration
@@ -62,34 +133,60 @@ THEME='theme={
62133}'
63134
64135# -----------------------------------------------------------------------------
65- # Verify startup script exists
136+ # Configure and start code-server as a background daemon.
137+ # The editor listens on port 3773 and serves the project workspace.
138+ # -----------------------------------------------------------------------------
139+ CODE_SERVER_CONFIG_DIR=" ${FULLING_HOME} /.config/code-server"
140+ CODE_SERVER_CONFIG_FILE=" ${CODE_SERVER_CONFIG_DIR} /config.yaml"
141+
142+ mkdir -p " $CODE_SERVER_CONFIG_DIR "
143+ cat > " $CODE_SERVER_CONFIG_FILE " << CODE_SERVER_CONFIG_EOF
144+ bind-addr: 0.0.0.0:3773
145+ auth: password
146+ password: ${EDITOR_PASSWORD}
147+ cert: false
148+ CODE_SERVER_CONFIG_EOF
149+ maybe_chown -R " $FULLING_USER :$FULLING_GROUP " " $CODE_SERVER_CONFIG_DIR "
150+
151+ if command -v code-server > /dev/null 2>&1 ; then
152+ echo " Starting code-server (port 3773)..."
153+ PASSWORD=" $EDITOR_PASSWORD " \
154+ HOME=" $HOME " \
155+ USER=" $USER " \
156+ LOGNAME=" $LOGNAME " \
157+ CODEX_HOME=" $CODEX_HOME " \
158+ nohup code-server " $FULLING_WORKSPACE " > /tmp/code-server.log 2>&1 &
159+ echo " ✓ code-server started (PID: $! )"
160+ else
161+ echo " ERROR: code-server is not installed"
162+ exit 1
163+ fi
164+
165+ # -----------------------------------------------------------------------------
166+ # Verify auth script exists
66167# -----------------------------------------------------------------------------
67- if [ ! -f /usr/local/bin/ttyd-startup.sh ]; then
68- echo " ERROR: ttyd-startup .sh not found at /usr/local/bin/ttyd-startup.sh "
168+ if [ ! -f " $TTYD_AUTH_SCRIPT " ]; then
169+ echo " ERROR: ttyd-auth .sh not found at $TTYD_AUTH_SCRIPT "
69170 exit 1
70171fi
71172
72173# -----------------------------------------------------------------------------
73- # Start ttyd with authentication
174+ # Start ttyd with token-based authentication
74175# -----------------------------------------------------------------------------
75176# Parameters:
76- # -T xterm-256color : Terminal type (widely supported)
177+ # -T xterm-256color : Terminal type
77178# -W : Enable WebSocket compression
78- # -a : Allow URL arguments (?arg=SESSION_ID) to be passed to command
79- # -c credential : HTTP Basic Auth (user:password)
179+ # -a : Allow URL arguments (?arg=TOKEN&arg=SESSION_ID)
80180# -t theme : Terminal color theme
81181#
82- # The command (ttyd-startup.sh) receives URL arguments:
83- # $1 = SESSION_ID (from ?arg=...)
84- #
85- # Authentication happens at HTTP/WebSocket level by ttyd.
86- # ttyd-startup.sh only handles session tracking for file upload cwd detection.
182+ # ttyd-auth.sh receives:
183+ # $1 = ACCESS_TOKEN (from first ?arg=)
184+ # $2 = SESSION_ID (from second ?arg=)
87185# -----------------------------------------------------------------------------
88- echo " Starting ttyd with HTTP Basic Auth ..."
186+ echo " Starting ttyd..."
89187exec ttyd \
90188 -T xterm-256color \
91189 -W \
92190 -a \
93- -c " $TTYD_CREDENTIAL " \
94191 -t " $THEME " \
95- /usr/local/bin/ttyd-startup.sh
192+ " $TTYD_AUTH_SCRIPT "
0 commit comments