Merge pull request 'chore(z-ai): retire harness — no active subscription' (#2) from retire-z-ai into main
This commit was merged in pull request #2.
This commit is contained in:
@@ -99,7 +99,7 @@ layers:
|
|||||||
|
|
||||||
### No secrets in this repo
|
### No secrets in this repo
|
||||||
|
|
||||||
This is a public framework repo. Secrets (provider API keys, SOPS-encrypted env files) belong in per-installation private repos attached at a lower CRS priority. The `z-ai/v1`, `minimax/v1`, `alibaba-model-studio/v1` contexts here declare the structure but leave `provider.sops.env` to the installation repo.
|
This is a public framework repo. Secrets (provider API keys) live in OpenBao via M22 ESO, never in the framework. The `minimax/v1` context here declares the structure; the live credential is mounted by ESO from the per-installation OpenBao instance. (Z.ai and Alibaba Model Studio contexts are retired but revivable — see agent-runtimes `planning/future/providers` F49 / F50.)
|
||||||
|
|
||||||
## Adding a New Harness Context
|
## Adding a New Harness Context
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
# This was previously broken: the wrapper `cat`d the ESO mount path which
|
# This was previously broken: the wrapper `cat`d the ESO mount path which
|
||||||
# the agent could not read. Discovered during the M22 Phase 9 audit; the
|
# the agent could not read. Discovered during the M22 Phase 9 audit; the
|
||||||
# wrapper-script approach was never re-validated post-cutover. Stage-and-
|
# wrapper-script approach was never re-validated post-cutover. Stage-and-
|
||||||
# wrapper-points-at-stage matches gitea-ssh / gitea-https / minimax / z-ai.
|
# wrapper-points-at-stage matches gitea-ssh / gitea-https / minimax.
|
||||||
#
|
#
|
||||||
# Rotation handling: per-container init. Long-running sessions need a
|
# Rotation handling: per-container init. Long-running sessions need a
|
||||||
# future scripts.control_loop hook to re-stage between operations.
|
# future scripts.control_loop hook to re-stage between operations.
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
# inside an init.sh-generated helper script, which silently failed because
|
# inside an init.sh-generated helper script, which silently failed because
|
||||||
# the helper runs as agent and the ESO file is root:root mode 0400. The
|
# the helper runs as agent and the ESO file is root:root mode 0400. The
|
||||||
# stage-and-helper-points-at-stage pattern matches gitea-ssh / minimax /
|
# stage-and-helper-points-at-stage pattern matches gitea-ssh / minimax /
|
||||||
# z-ai / anthropic-cloud-paul-oauth.
|
# anthropic-cloud-paul-oauth.
|
||||||
#
|
#
|
||||||
# Rotation handling: per-container init. Ephemeral container agents
|
# Rotation handling: per-container init. Ephemeral container agents
|
||||||
# always pick up the latest mounted token. Long-running sessions need a
|
# always pick up the latest mounted token. Long-running sessions need a
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
kind: context
|
|
||||||
name: z-ai
|
|
||||||
version: 1
|
|
||||||
description: "Z.ai GLM coding plan — Anthropic-compatible proxy"
|
|
||||||
requires: []
|
|
||||||
provides: [claude-code]
|
|
||||||
|
|
||||||
env:
|
|
||||||
ANTHROPIC_BASE_URL: "https://api.z.ai/api/anthropic"
|
|
||||||
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: "1"
|
|
||||||
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1"
|
|
||||||
DISABLE_PROMPT_CACHING: "1"
|
|
||||||
|
|
||||||
secrets_required:
|
|
||||||
- name: z-ai
|
|
||||||
account_ref: "z-ai"
|
|
||||||
mount_path: /run/agent/secrets/z-ai
|
|
||||||
# 0400 (root-only) — defense in depth. The agent user cannot read this
|
|
||||||
# mount. init.sh runs as root and stages the auth_token into the agent's
|
|
||||||
# home with mode 0600. apiKeyHelper points at the staged copy. Matches
|
|
||||||
# the gitea-ssh pattern; if the ESO Secret later carries additional
|
|
||||||
# files (e.g. base_url is already there), they remain inaccessible.
|
|
||||||
mode: "0400"
|
|
||||||
|
|
||||||
scripts:
|
|
||||||
init: "./init.sh"
|
|
||||||
|
|
||||||
# TODO: Add network_hosts for api.z.ai when context harnesses support it
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# z-ai init — stage the auth_token for the agent user and wire apiKeyHelper.
|
|
||||||
#
|
|
||||||
# Threat model: keep the ESO mount root-only (mode 0400) so the agent user
|
|
||||||
# cannot directly read /run/agent/secrets/z-ai/*. init.sh runs as root and
|
|
||||||
# stages a single per-secret copy of auth_token into the agent's home with
|
|
||||||
# mode 0600. Only that staged file is reachable by the runtime; any other
|
|
||||||
# files in the ESO Secret (e.g. legacy base_url) stay root-only.
|
|
||||||
#
|
|
||||||
# Rotation handling: this is a one-shot copy at container start. Ephemeral
|
|
||||||
# container agents always run init.sh per task — no rotation gap there.
|
|
||||||
# Long-running sessions need a future scripts.control_loop hook to refresh
|
|
||||||
# the copy between agent CLI invocations.
|
|
||||||
#
|
|
||||||
# Auth wire-up: apiKeyHelper output routes to `Authorization: Bearer <value>`
|
|
||||||
# when ANTHROPIC_BASE_URL is non-anthropic.com (set in harness.yaml to
|
|
||||||
# https://api.z.ai/api/anthropic). The secret value never enters env or any
|
|
||||||
# process' /proc/<pid>/environ.
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
ESO_AUTH_TOKEN="/run/agent/secrets/z-ai/auth_token"
|
|
||||||
|
|
||||||
if [ ! -r "$ESO_AUTH_TOKEN" ]; then
|
|
||||||
echo "ERROR: $ESO_AUTH_TOKEN not readable. Check ESO ExternalSecret acct-<z-ai-id>." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
AGENT_USER="${AGENT_USER:-agent}"
|
|
||||||
AGENT_HOME=$(getent passwd "$AGENT_USER" | cut -d: -f6)
|
|
||||||
if [ -z "$AGENT_HOME" ] || [ ! -d "$AGENT_HOME" ]; then
|
|
||||||
AGENT_HOME="/home/$AGENT_USER"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Stage the auth_token into a per-secret path owned by agent, mode 0600.
|
|
||||||
STAGED_KEY_DIR="$AGENT_HOME/.claude/secrets"
|
|
||||||
STAGED_KEY="$STAGED_KEY_DIR/z-ai-auth-token"
|
|
||||||
mkdir -p "$STAGED_KEY_DIR"
|
|
||||||
chown "$AGENT_USER:" "$STAGED_KEY_DIR" 2>/dev/null || true
|
|
||||||
chmod 0700 "$STAGED_KEY_DIR"
|
|
||||||
install -m 0600 -o "$AGENT_USER" -g "$AGENT_USER" "$ESO_AUTH_TOKEN" "$STAGED_KEY"
|
|
||||||
|
|
||||||
# Wire apiKeyHelper at the staged copy.
|
|
||||||
CONFIG_DIR="${CLAUDE_CONFIG_DIR:-$AGENT_HOME/.claude}"
|
|
||||||
mkdir -p "$CONFIG_DIR"
|
|
||||||
chown "$AGENT_USER:" "$CONFIG_DIR" 2>/dev/null || true
|
|
||||||
chmod 0755 "$CONFIG_DIR"
|
|
||||||
|
|
||||||
SETTINGS_FILE="$CONFIG_DIR/settings.json"
|
|
||||||
|
|
||||||
if [ -f "$SETTINGS_FILE" ] && command -v jq >/dev/null 2>&1; then
|
|
||||||
TMP=$(mktemp)
|
|
||||||
jq --arg helper "cat $STAGED_KEY" \
|
|
||||||
'. + {apiKeyHelper: $helper}' \
|
|
||||||
"$SETTINGS_FILE" > "$TMP"
|
|
||||||
mv "$TMP" "$SETTINGS_FILE"
|
|
||||||
else
|
|
||||||
cat > "$SETTINGS_FILE" <<EOF
|
|
||||||
{
|
|
||||||
"apiKeyHelper": "cat $STAGED_KEY"
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
fi
|
|
||||||
|
|
||||||
chown "$AGENT_USER:" "$SETTINGS_FILE" 2>/dev/null || true
|
|
||||||
chmod 0644 "$SETTINGS_FILE"
|
|
||||||
|
|
||||||
echo "z-ai auth_token staged at $STAGED_KEY (0600 $AGENT_USER:$AGENT_USER)"
|
|
||||||
echo "z-ai apiKeyHelper wired in $SETTINGS_FILE"
|
|
||||||
Reference in New Issue
Block a user