Skip to content

feat(security): token-issuance UI + served agent-skill (server-verified step-up; anon agent skill)#1619

Open
JasonWildMe wants to merge 10 commits into
mainfrom
token-ui-agent-skill
Open

feat(security): token-issuance UI + served agent-skill (server-verified step-up; anon agent skill)#1619
JasonWildMe wants to merge 10 commits into
mainfrom
token-ui-agent-skill

Conversation

@JasonWildMe

Copy link
Copy Markdown
Collaborator

Summary

Builds on the token-scoped read API (merged in #1613) with two user-facing pieces:

A — Token-issuance UI. A logged-in user can mint a short-lived bearer token from a new API Access page (avatar menu → API Access). A password step-up is required and enforced server-side: AuthToken now requires and verifies a fresh HTTP Basic credential (User.checkPassword, constant-time, mirroring login) and rejects session-only mints — a stolen/unlocked session or same-origin script can no longer mint without the password. The React mint call uses a cookie-less fetch(credentials:"omit"); the token is shown once and held only in component state. Cache-Control: no-store on the response.

B — Served agent skill. GET /api/v3/agent-skill (anonymous) serves a curated markdown that teaches a user's AI agent the token-scoped API, the OpenSearch schema/fields, how to obtain a token, and — importantly — to never accept the user's username/password, only a short-lived token. A SearchApi.TOKEN_ALLOWED_INDICES constant was extracted so a drift-guard test pins the skill's index claims to the real allowlist; another test forbids leaking internal ACL field names.

What changed

  • User.checkPassword(clearText) — constant-time verify against the stored salted hash.
  • AuthToken — server-side step-up (fresh Basic required; session-only → 401; wrong password → 401), no-store, audit logging (no secrets).
  • AgentSkill servlet + src/main/resources/agent-skill.md + web.xml (anon rule, exact mapping).
  • SearchApi.TOKEN_ALLOWED_INDICES constant (behavior-preserving refactor of the inline allowlist).
  • Frontend: useMintToken (cookie-less, UTF-8 Basic), ApiAccessPage (step-up modal + one-time token display), /api-access route, avatar menu item.

Testing

  • Backend: 48 tests green (UserCheckPasswordTest, AuthTokenTest updated, AuthTokenStepUpTest, AgentSkillTest, EndpointAuthWiringTest, plus SearchApiTokenAuthTest/SearchApiChildIndexTest confirm the allowlist refactor didn't regress).
  • Frontend: useMintToken, ApiAccessPage, avatar-link tests green.
  • No package.json / package-lock.json changes.

Process

Brainstormed → spec → plan → subagent-driven implementation with per-task spec + code-quality review. Codex reviewed the design, the plan, and the final code (verdict: READY TO MERGE; the step-up bypass it flagged in the design was closed, and a UTF-8 Basic-encoding bug it caught in code review is fixed + tested).

Design spec + plan are included under docs/superpowers/.

🤖 Generated with Claude Code

JasonWildMe and others added 9 commits June 11, 2026 15:29
…eviewed)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ession-only

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…SearchApi allowlist constant + drift-guard

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Also adds missing @testing-library/dom peer dependency (required by
@testing-library/react@16; was absent, breaking all RTL-based tests).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…d username, copy fix

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codecov-commenter

codecov-commenter commented Jun 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 74.19355% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 51.63%. Comparing base (cd55bfc) to head (367ea0f).
⚠️ Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
frontend/src/pages/ApiAccess/ApiAccessPage.jsx 78.04% 8 Missing and 1 partial ⚠️
frontend/src/models/auth/useMintToken.js 65.00% 7 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1619      +/-   ##
==========================================
+ Coverage   51.50%   51.63%   +0.13%     
==========================================
  Files         308      310       +2     
  Lines       12100    12162      +62     
  Branches     3920     3933      +13     
==========================================
+ Hits         6232     6280      +48     
- Misses       5578     5598      +20     
+ Partials      290      284       -6     
Flag Coverage Δ
backend 51.63% <74.19%> (+0.13%) ⬆️
frontend 51.63% <74.19%> (+0.13%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…ces section

The served skill said "See the field reference for full descriptions" but no
such document or endpoint exists. Reword to own the inline field list, and add
a References section linking the general Wildbook docs (wildbook.docs.wildme.org)
while marking this skill authoritative for the token API where the two differ.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants