Skip to content

Commit 314e1a2

Browse files
Pigbibicodex
andcommitted
fix: keep audit service token out of systemd unit
Co-Authored-By: Codex <noreply@openai.com>
1 parent 6b5938b commit 314e1a2

3 files changed

Lines changed: 37 additions & 5 deletions

File tree

ops/codex-audit/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ Repo secrets `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` are written to
1717
The same root-owned file is imported by `codex-audit-service`; no provider key
1818
is placed in repository code, workflow output, or an inline systemd setting.
1919

20+
## Service-token storage
21+
22+
If the optional `CODEX_AUDIT_SERVICE_TOKEN` is configured for the dashboard's
23+
read-only fallback, the deployment writes it to
24+
`/etc/codex-audit-bridge/service-token.env` with mode `0600`. The systemd unit
25+
references that file; it never embeds the token in the unit text. An OIDC
26+
caller remains the required path for GitHub Actions, so this fallback must not
27+
be copied into repository variables or workflow logs.
28+
2029
- **auto**: push to `main` that touches catalog paths triggers deploy
2130
- **manual**: Actions → Deploy Model Catalog Sync → `deploy` / `inspect` / `sync-now`
2231

scripts/deploy_codex_audit_service.sh

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ ALLOWED_DIRECT_REPOSITORIES="${CODEX_AUDIT_SERVICE_ALLOWED_DIRECT_REPOSITORIES:-
2222
ALLOWED_SOURCE_REPOSITORIES="${CODEX_AUDIT_SERVICE_ALLOWED_SOURCE_REPOSITORIES:-QuantStrategyLab/AIAuditBridge,QuantStrategyLab/BinancePlatform,QuantStrategyLab/CharlesSchwabPlatform,QuantStrategyLab/CnEquitySnapshotPipelines,QuantStrategyLab/CnEquityStrategies,QuantStrategyLab/CryptoLivePoolPipelines,QuantStrategyLab/CryptoStrategies,QuantStrategyLab/FirstradePlatform,QuantStrategyLab/HkEquitySnapshotPipelines,QuantStrategyLab/HkEquityStrategies,QuantStrategyLab/IBKRGatewayManager,QuantStrategyLab/InteractiveBrokersPlatform,QuantStrategyLab/LongBridgePlatform,QuantStrategyLab/MarketSignalSources,QuantStrategyLab/PoliticalEventTrackingResearch,QuantStrategyLab/QmtPlatform,QuantStrategyLab/QuantAdvisorResearch,QuantStrategyLab/QuantPlatformKit,QuantStrategyLab/QuantRuntimeSettings,QuantStrategyLab/QuantStrategyPlugins,QuantStrategyLab/ResearchSignalContextPipelines,QuantStrategyLab/SchwabTokenAutoRefresher,QuantStrategyLab/UsEquitySnapshotPipelines,QuantStrategyLab/UsEquityStrategies}"
2323
JOB_DIR="${CODEX_AUDIT_SERVICE_JOB_DIR:-/var/lib/codex-audit-bridge/jobs}"
2424
ADMIN_ENV_FILE="${CODEX_AUDIT_SERVICE_ADMIN_ENV_FILE:-/etc/codex-audit-bridge/admin.env}"
25+
SERVICE_TOKEN_ENV_FILE="${CODEX_AUDIT_SERVICE_TOKEN_ENV_FILE:-/etc/codex-audit-bridge/service-token.env}"
2526
# The model-catalog deploy owns the provider-key file. Reuse that root-owned
2627
# file instead of duplicating API keys in a second deployment path.
2728
PROVIDER_ENV_FILE="${CODEX_AUDIT_SERVICE_PROVIDER_ENV_FILE:-/etc/codex-audit-bridge/model-catalog.env}"
@@ -226,6 +227,25 @@ write_admin_env_file_if_needed() {
226227
trap - RETURN
227228
}
228229

230+
write_service_token_env_file_if_needed() {
231+
# The dashboard fallback token is optional. When supplied, it must stay in
232+
# a root-only EnvironmentFile instead of the world-readable systemd unit.
233+
# A deploy without this optional secret preserves the current file so it
234+
# cannot silently revoke a dashboard session.
235+
if [ -z "${CODEX_AUDIT_SERVICE_TOKEN:-}" ]; then
236+
return
237+
fi
238+
local tmp
239+
tmp="$(mktemp)"
240+
trap 'rm -f "$tmp"' RETURN
241+
chmod 0600 "$tmp"
242+
printf 'CODEX_AUDIT_SERVICE_TOKEN=%s\n' "$CODEX_AUDIT_SERVICE_TOKEN" >"$tmp"
243+
sudo install -d -m 0700 "$(dirname "$SERVICE_TOKEN_ENV_FILE")"
244+
sudo install -m 0600 -o root -g root "$tmp" "$SERVICE_TOKEN_ENV_FILE"
245+
rm -f "$tmp"
246+
trap - RETURN
247+
}
248+
229249
write_default_execution_policy_if_missing() {
230250
local policy_path="${EXECUTION_POLICY_FILE}"
231251
local policy_dir
@@ -355,10 +375,6 @@ write_audit_service_unit() {
355375
if [ -n "$AUDIT_REASONING_EFFORT" ]; then
356376
audit_reasoning_effort_line="Environment=CODEX_AUDIT_SERVICE_REASONING_EFFORT=${AUDIT_REASONING_EFFORT}"
357377
fi
358-
audit_token_line=""
359-
if [ -n "${CODEX_AUDIT_SERVICE_TOKEN:-}" ]; then
360-
audit_token_line="Environment=CODEX_AUDIT_SERVICE_TOKEN=${CODEX_AUDIT_SERVICE_TOKEN}"
361-
fi
362378
sudo tee "/etc/systemd/system/${AUDIT_SERVICE_NAME}.service" >/dev/null <<EOF_UNIT
363379
[Unit]
364380
Description=QuantStrategyLab Codex audit service
@@ -389,10 +405,10 @@ Environment=CODEX_AUDIT_SERVICE_OPENAI_USAGE_WINDOW_DAYS=${OPENAI_USAGE_WINDOW_D
389405
Environment=CODEX_AUDIT_SERVICE_ANTHROPIC_USAGE_WINDOW_DAYS=${ANTHROPIC_USAGE_WINDOW_DAYS}
390406
Environment=CODEX_AUDIT_SERVICE_SANDBOX=read-only
391407
EnvironmentFile=-${ADMIN_ENV_FILE}
408+
EnvironmentFile=-${SERVICE_TOKEN_ENV_FILE}
392409
EnvironmentFile=-${PROVIDER_ENV_FILE}
393410
${audit_model_line}
394411
${audit_reasoning_effort_line}
395-
${audit_token_line}
396412
ExecStart=/usr/bin/env python3 -m service.ai_gateway_service
397413
Restart=on-failure
398414
RestartSec=5
@@ -646,6 +662,7 @@ deploy() {
646662
sudo install -d -m 0700 -o "$runner_user" -g "$runner_user" "$JOB_DIR"
647663
write_default_execution_policy_if_missing
648664
write_admin_env_file_if_needed
665+
write_service_token_env_file_if_needed
649666
write_audit_service_unit
650667
write_managed_audit_service_dropin
651668
sudo systemctl daemon-reload

tests/test_run_monthly_codex_audit.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2490,13 +2490,19 @@ def test_vps_deploy_adds_nginx_audit_route_without_router_service(self) -> None:
24902490
self.assertIn("ANTHROPIC_USAGE_WINDOW_DAYS=", deploy_script)
24912491
self.assertIn("CODEX_AUDIT_SERVICE_ADMIN_ENV_FILE", deploy_script)
24922492
self.assertIn("EnvironmentFile=-${ADMIN_ENV_FILE}", deploy_script)
2493+
self.assertIn("CODEX_AUDIT_SERVICE_TOKEN_ENV_FILE", deploy_script)
2494+
self.assertIn("EnvironmentFile=-${SERVICE_TOKEN_ENV_FILE}", deploy_script)
2495+
self.assertIn("write_service_token_env_file_if_needed", deploy_script)
2496+
self.assertIn("a root-only EnvironmentFile instead of the world-readable systemd unit", deploy_script)
24932497
self.assertIn("CODEX_AUDIT_SERVICE_PROVIDER_ENV_FILE", deploy_script)
24942498
self.assertIn("EnvironmentFile=-${PROVIDER_ENV_FILE}", deploy_script)
24952499
self.assertIn("/etc/codex-audit-bridge/model-catalog.env", deploy_script)
24962500
self.assertIn("sudo install -m 0600 -o root -g root", deploy_script)
24972501
self.assertIn('sudo rm -f "$ADMIN_ENV_FILE"', deploy_script)
24982502
self.assertNotIn("Environment=OPENAI_ADMIN_KEY=", deploy_script)
24992503
self.assertNotIn("Environment=ANTHROPIC_ADMIN_KEY=", deploy_script)
2504+
self.assertNotIn('audit_token_line=""', deploy_script)
2505+
self.assertNotIn('Environment=CODEX_AUDIT_SERVICE_TOKEN=${CODEX_AUDIT_SERVICE_TOKEN}', deploy_script)
25002506
self.assertNotIn("^OPENAI_ADMIN_KEY", deploy_script)
25012507
self.assertNotIn("^ANTHROPIC_ADMIN_KEY", deploy_script)
25022508
self.assertNotIn("^CODEX_AUDIT_SERVICE_TOKEN", deploy_script)

0 commit comments

Comments
 (0)