@@ -21,7 +21,13 @@ GATEWAY_CA="${AGENT_GATEWAY_DEMO_GATEWAY_CA:-$REPO_ROOT/certs/server-ca.pem}"
2121MOCK_CA=" ${AGENT_GATEWAY_DEMO_MOCK_CA:- $REPO_ROOT / certs/ mock-ca.pem} "
2222SIDECAR_BIN=" $REPO_ROOT /target/debug/agent_gateway_sidecar"
2323GATEWAY_IMAGE=" ${AGENT_GATEWAY_DEMO_GATEWAY_IMAGE:- ghcr.io/ sl5taskforce/ agent-gateway: main} "
24- VERIFY_TIMEOUT_SECONDS=" ${AGENT_GATEWAY_DEMO_VERIFY_TIMEOUT_SECONDS:- 120} "
24+ RESET_SERVER_PORT=" ${AGENT_GATEWAY_DEMO_RESET_SERVER_PORT:- 8765} "
25+ PIDS_DIR=" $REPO_ROOT /.run"
26+
27+ RESET_MODE=false
28+ if [[ " ${1:- } " == " --reset" ]]; then
29+ RESET_MODE=true
30+ fi
2531
2632export COMPOSE_PROJECT_NAME
2733export AGENT_GATEWAY_DEMO_GATEWAY_IMAGE=" $GATEWAY_IMAGE "
@@ -97,51 +103,117 @@ state_dir() {
97103 printf ' %s/%s\n' " $STATE_ROOT " " $HANDLE "
98104}
99105
100- print_verification_diagnostics () {
101- local sidecar_log
102- sidecar_log=" $( state_dir) /sidecar.log"
106+ clear_enrollment () {
107+ echo " ==> Stopping sidecar"
108+ local sidecar_pid_file
109+ sidecar_pid_file=" $( state_dir) /sidecar_pid"
110+ if [[ -f " $sidecar_pid_file " ]]; then
111+ local pid
112+ pid=" $( < " $sidecar_pid_file " ) "
113+ kill " $pid " 2> /dev/null || true
114+ fi
115+
116+ echo " ==> Clearing agent state and TPM store"
117+ rm -rf " $STATE_ROOT " " $TPM2_PKCS11_STORE "
118+
119+ echo " ==> Clearing enrollment records from database"
120+ psql " $DATABASE_URL " -v ON_ERROR_STOP=1 << 'SQL '
121+ DELETE FROM permission_registry;
122+ DELETE FROM principal_key_permissions;
123+ DELETE FROM principal_signing_keys;
124+ SQL
125+ }
126+
127+ enroll () {
128+ demo_env=(
129+ " AGENT_GATEWAY_DATABASE_URL=$DATABASE_URL "
130+ " AGENT_GATEWAY_DEMO_GATEWAY=$GATEWAY "
131+ " AGENT_GATEWAY_DEMO_GATEWAY_CA=$GATEWAY_CA "
132+ " AGENT_GATEWAY_DEMO_MOCK_CA=$MOCK_CA "
133+ " AGENT_GATEWAY_DEMO_SIDECAR_BIN=$SIDECAR_BIN "
134+ " AGENT_GATEWAY_DEMO_STATE_DIR=$STATE_ROOT "
135+ " AGENT_GATEWAY_TPM_USER_PIN=$USER_PIN "
136+ " AGENT_GATEWAY_TPM_SO_PIN=$SO_PIN "
137+ " AGENT_GATEWAY_RESET_TPM_STORE=false"
138+ " CLAUDE_CODE_PROXY_RESOLVES_HOSTS=1"
139+ " CURL_CA_BUNDLE=$MOCK_CA "
140+ " NODE_EXTRA_CA_CERTS=$MOCK_CA "
141+ " SSL_CERT_FILE=$MOCK_CA "
142+ " TPM2_PKCS11_STORE=$TPM2_PKCS11_STORE "
143+ " AGENT_GATEWAY_DEMO_DASHBOARD_URL=http://localhost:3000"
144+ )
145+
146+ echo " ==> Registering demo principal $PRINCIPAL "
147+ env " ${demo_env[@]} " " $REPO_ROOT /registry-cli/register-principal-key.sh" " $PRINCIPAL "
148+
149+ echo " ==> Granting demo scopes"
150+ env " ${demo_env[@]} " " $REPO_ROOT /registry-cli/grant-principal-scope.sh" " $PRINCIPAL " docstore messaging api.anthropic.com
151+
152+ echo " ==> Creating demo agent $HANDLE "
153+ env " ${demo_env[@]} " " $SCRIPT_DIR /demo-agent.sh" create \
154+ --identity " $IDENTITY " \
155+ --handle " $HANDLE " \
156+ --grant docstore \
157+ --grant api.anthropic.com > /dev/null
158+ }
159+
160+ start_reset_server () {
161+ mkdir -p " $PIDS_DIR "
103162
104- echo " Check the gateway, sidecar, and mock service logs before retrying." >&2
105- echo " Sidecar log: $sidecar_log " >&2
106- if [[ -f " $sidecar_log " ]]; then
107- echo >&2
108- echo " Recent sidecar log lines:" >&2
109- tail -n 80 " $sidecar_log " >&2 || true
163+ # Kill any existing reset server
164+ if [[ -f " $PIDS_DIR /reset-server.pid" ]]; then
165+ kill " $( < " $PIDS_DIR /reset-server.pid" ) " 2> /dev/null || true
166+ rm -f " $PIDS_DIR /reset-server.pid"
110167 fi
168+
169+ local setup_script=" $SCRIPT_DIR /setup.sh"
170+ nohup node -e "
171+ const http = require('http');
172+ const { spawn } = require('child_process');
173+ http.createServer((req, res) => {
174+ if (req.method !== 'POST' || new URL(req.url, 'http://x').pathname !== '/reset') {
175+ res.writeHead(404); res.end(); return;
176+ }
177+ const proc = spawn('bash', ['$setup_script ', '--reset'], { stdio: 'inherit' });
178+ proc.on('exit', code => {
179+ res.writeHead(code === 0 ? 200 : 500, {'Content-Type': 'application/json'});
180+ res.end(JSON.stringify({ ok: code === 0 }));
181+ });
182+ }).listen($RESET_SERVER_PORT , '0.0.0.0', () => {
183+ process.stdout.write('Reset server listening on $RESET_SERVER_PORT \n');
184+ });
185+ " > " $PIDS_DIR /reset-server.log" 2>&1 &
186+ echo $! > " $PIDS_DIR /reset-server.pid"
187+ echo " ==> Reset server started on port $RESET_SERVER_PORT "
111188}
112189
113- demo_env=(
114- " AGENT_GATEWAY_DATABASE_URL=$DATABASE_URL "
115- " AGENT_GATEWAY_DEMO_GATEWAY=$GATEWAY "
116- " AGENT_GATEWAY_DEMO_GATEWAY_CA=$GATEWAY_CA "
117- " AGENT_GATEWAY_DEMO_MOCK_CA=$MOCK_CA "
118- " AGENT_GATEWAY_DEMO_SIDECAR_BIN=$SIDECAR_BIN "
119- " AGENT_GATEWAY_DEMO_STATE_DIR=$STATE_ROOT "
120- " AGENT_GATEWAY_TPM_USER_PIN=$USER_PIN "
121- " AGENT_GATEWAY_TPM_SO_PIN=$SO_PIN "
122- " AGENT_GATEWAY_RESET_TPM_STORE=false"
123- " CLAUDE_CODE_PROXY_RESOLVES_HOSTS=1"
124- " CURL_CA_BUNDLE=$MOCK_CA "
125- " NODE_EXTRA_CA_CERTS=$MOCK_CA "
126- " SSL_CERT_FILE=$MOCK_CA "
127- " TPM2_PKCS11_STORE=$TPM2_PKCS11_STORE "
128- )
190+ # ── Main ──────────────────────────────────────────────────────────────────────
129191
130192select_compose
131193require_cmd cargo
132194require_cmd openssl
133195require_cmd psql
134- require_cmd timeout
196+ require_cmd node
135197
136198cd " $REPO_ROOT "
137199
200+ if [[ " $RESET_MODE " == " true" ]]; then
201+ clear_enrollment
202+ enroll
203+ echo " Reset complete."
204+ exit 0
205+ fi
206+
138207echo " ==> Generating demo TLS certificates"
139208" $SCRIPT_DIR /generate-server-certs.sh"
140209
141210if [[ ! -f " $REPO_ROOT /config.toml" ]]; then
142211 echo " ==> Creating config.toml from config.example.toml"
143212 cp " $REPO_ROOT /config.example.toml" " $REPO_ROOT /config.toml"
144213fi
214+ # Ensure the gateway (running in Docker) sends OTLP to the collector service name,
215+ # not localhost (which would be the gateway container itself).
216+ sed -i ' s|otlp_endpoint = "http://localhost:4317"|otlp_endpoint = "http://otel-collector:4317"|' " $REPO_ROOT /config.toml"
145217
146218echo " ==> Building local sidecar"
147219cargo build -p agent_gateway_sidecar
@@ -153,51 +225,17 @@ compose up -d --force-recreate postgres mock-services
153225wait_for_postgres
154226apply_migrations
155227
156- echo " ==> Starting gateway"
228+ echo " ==> Starting gateway, otel-collector, and dashboard "
157229compose up -d --force-recreate gateway otel-collector dashboard
158230
159- echo " ==> Registering demo principal $PRINCIPAL "
160- env " ${demo_env[@]} " " $REPO_ROOT /registry-cli/register-principal-key.sh" " $PRINCIPAL "
161-
162- echo " ==> Granting demo scopes"
163- env " ${demo_env[@]} " " $REPO_ROOT /registry-cli/grant-principal-scope.sh" " $PRINCIPAL " docstore messaging api.anthropic.com
164-
165- echo " ==> Creating demo agent $HANDLE "
166- env " ${demo_env[@]} " " $SCRIPT_DIR /demo-agent.sh" create \
167- --identity " $IDENTITY " \
168- --handle " $HANDLE " \
169- --grant docstore \
170- --grant api.anthropic.com \
171- --grant messaging > /dev/null
172-
173- echo " ==> Verifying Claude Code HTTP requests through the gateway"
174- if ! timeout " $VERIFY_TIMEOUT_SECONDS " env " ${demo_env[@]} " " $SCRIPT_DIR /demo-agent.sh" prompt " $HANDLE " --prompt \
175- " Access https://docstore/health using curl and return only the raw response body.
176- Return only the raw response body." ; then
177- cat >&2 << EOF
178- error: Claude Code could not fetch https://docstore/health through the demo gateway.
179-
180- Expected environment:
181- HTTPS_PROXY=http://127.0.0.1:3128
182- CURL_CA_BUNDLE=$MOCK_CA
183- NODE_EXTRA_CA_CERTS=$MOCK_CA
184- SSL_CERT_FILE=$MOCK_CA
185- CLAUDE_CODE_PROXY_RESOLVES_HOSTS=1
186- AGENT_GATEWAY_DEMO_SIDECAR_BIN=$SIDECAR_BIN
187-
188- EOF
189- print_verification_diagnostics
190- exit 1
191- fi
192-
193- rm -f " $( state_dir) /claude_started"
231+ enroll
232+ start_reset_server
194233
195234cat << EOF
196235
197236Demo is ready.
198237
199- Dashboard URL:
200- http://localhost:3000
238+ Dashboard: http://localhost:3000
201239
202240Mock service URLs available through the gateway:
203241 https://docstore/health
0 commit comments