Heicode rotated NewAPI service token (fingerprint 25b85d67…b1d6) per §7.16.7.
Walked through §7.7.2.1 flow:
1. Read Docs/heicode-svc-token.txt — fingerprint matched
2. kubectl create secret generic heicode-newapi (key=service-token)
3. rollout restart — completed
4. P4 smoke 4/4 with 55@55.com — balance/models/usage/logs all 200
5. Deleted local Docs/heicode-svc-token.txt
6. This §7.17 ack
Answer to Heicode's lookup question:
Their `zsbgnw@gmail.com → USER_NOT_FOUND` observation was a side-effect of
the stale token: while their new token was staged but our k8s secret still
held the previous value, every NewAPI call returned 401, and our
resolve_user_id_by_email() catches HeicodeNewAPIError and returns None —
which the P4 router translates to 404 HEICODE_USER_NOT_FOUND.
Direct re-test from inside the pod after rotation:
`GET /api/user/search?keyword=zsbgnw@gmail.com&group=` → 200, 1 item,
id=22 email=zsbgnw@gmail.com username=chenchen. Our query path is exactly
what they suggested (`/api/user/search` with empty `group`), and we filter
by email field downstream — implementation is fine.
Bonus finding: post-rotation `/balance` for zsbgnw@gmail.com returns
502 HEICODE_NEWAPI_UPSTREAM_ERROR because user 22 is super-admin and our
admin token holder (user 26) cannot read same-or-higher-level users
("No permission to access users of same or higher level"). NewAPI returns
HTTP 200 with success=false, our client correctly raises HeicodeNewAPIError.
This is an authorization policy on their side, not a bug — three options
proposed in §7.17.3 for product decision.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two small follow-ups to the register hardening + Heicode P4 work:
1. heicode_client.list_user_models: the path `/api/user/{id}/models`
prescribed in §7.11.2 returns 404 `Invalid URL` on the live Heicode
NewAPI — that path is not registered on their router. Switched to
`/api/user/models` (no path segment), which Heicode binds to the
`New-Api-User: 26` admin header. End-to-end P4 smoke now 4/4 with
user 55@55.com (id=2 on Heicode): /balance /models /usage /logs.
Future: if Heicode ships an "admin-replaces-user" path, switch back
and pass the actual heicode_user_id.
2. routes/auth.register: previously line-744 SELECT only checked
req.username, but line 778 falls back to email.split("@")[0] when
blank — so two users registering with alice@foo.com and alice@bar.com
would both clear the predcheck, then the second would IntegrityError
on flush. Now predcheck uses `effective_username` matching what'll
actually be inserted.
Also append §7.15 to Heicode-对接进度与待办.md:
- 4-item agent-manager / Vault / Workload-Identity audit results
- §7.13 token rotation acknowledgement
- P4 end-to-end first-pass results
- This-session internal security hardening summary
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>