Skip to content

feat/331 admin webhook api#8

Open
aaronwong1989 wants to merge 7 commits into
mainfrom
feat/331-admin-webhook-api
Open

feat/331 admin webhook api#8
aaronwong1989 wants to merge 7 commits into
mainfrom
feat/331-admin-webhook-api

Conversation

@aaronwong1989
Copy link
Copy Markdown
Owner

HotPlexBot and others added 7 commits March 22, 2026 14:29
โ€ฆo#331)

- Add AdminSession, AdminSessionStats, AdminEvent, AdminHealth types
- Add AdminError, BatchStopRequest/Response types
- Implement constant-time auth middleware with X-Admin-Key header
- Add comprehensive auth middleware tests
- Map engine.SessionStatus to admin API status strings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
โ€ฆterface (Refs hrygo#331)

Implemented comprehensive Admin Webhook API at /api/v1/admin/ with:

Session Management:
- GET  /sessions             - List sessions with pagination
- GET  /sessions/{id}         - Get session details
- POST /sessions/{id}/stop   - Stop single session
- POST /sessions/batch-stop  - Batch stop sessions

Health & Metrics:
- GET /health                - Detailed health with subsystem checks
- GET /metrics               - Prometheus-compatible metrics text format
- POST /drain                - Enter drain mode
- GET  /drain                - Get drain status
- DELETE /drain              - Exit drain mode

Configuration (read-only):
- GET /config                       - Safe engine config view
- GET /config/allowed_tools         - Allowed tools list
- GET /config/disallowed_tools      - Disallowed tools list

Audit & Events:
- GET /events                       - Event log with cursor pagination
- GET /sessions/{id}/transcript     - Session transcript

Features:
- X-Admin-Key auth with constant-time comparison
- Optional auth bypass when no key configured
- Thread-safe in-memory ring buffer (10k events)
- Integration with Engine drain mode
- Comprehensive unit tests (60+ tests)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- auth.go: check w.Write return value
- auth_test.go: check w.Write return value
- health_handler.go: check w.Write return value
- session_handler.go: check json.Encode return value
- event_buffer_test.go: use _ for unused total variable
- admin.go: use copy() instead of loop

Refs hrygo#331
Introduce internal/adminapi/ as the canonical source for cross-package
admin domain code (ErrorCode, MapSessionStatus, WriteJSON, WriteError),
eliminating duplication between internal/admin (CLI) and
internal/server/admin (Webhook API).

- internal/adminapi/: new shared domain package
- internal/admin/: re-export via type aliases, use shared helpers
- internal/server/admin/: use shared domain functions
- internal/admin/handler_test.go: update to adminapi helpers
- internal/server/admin/auth_test.go: update to adminapi.WriteError

Refs hrygo#331
- Remove duplicate AdminError/ErrorDetail types in server/admin/types.go
- Use type aliases from adminapi for error types
- Replace raw string error codes with typed ErrorCode constants
- Use adminapi.MapSessionStatus() in admin CLI handler
- Add ErrCodeEngineNotInitialized to shared domain
- Deprecate local NewAdminError* functions (use adminapi.NewError*)

Refs hrygo#331
Rename authentication header from X-Admin-Key to X-API-Key,
which is the industry-standard convention for API key authentication.

Refs hrygo#331
## Changes

### Core Improvements
- **Unified Auth Middleware** (internal/adminapi/auth.go)
  - New shared authentication module supporting dual modes:
    - `AuthModeBearer` (OAuth2 standard): Authorization: Bearer <token>
    - `AuthModeAPIKey` (simplified): X-API-Key: <key>
  - Constant-time comparison prevents timing attacks
  - Configurable logging with structured slog
  - Bypass mode when adminKey is empty (dev/unsecured)

### Refactored Components
- **internal/admin** (CLI Admin API)
  - Simplified middleware using shared adminapi.AuthMiddleware
  - Maintains Bearer token authentication (OAuth2 standard)
  - Updated signature: NewMiddleware(token, logger)

- **internal/server/admin** (Webhook Admin API)
  - Delegates to shared adminapi.AuthMiddleware
  - Uses API Key authentication mode
  - Removed duplicate code (keyPrefix, subtle.ConstantTimeCompare)

### Code Quality Improvements
- **DRY/SOLID Compliance**
  - Single source of truth for authentication logic
  - Shared domain utilities (ParsePagination, WriteJSON, WriteError)
  - Eliminated redundant implementations

- **Security**
  - Unified constant-time comparison across all admin APIs
  - Consistent error codes (ErrCodeUnauthorized)
  - Enhanced logging with authentication mode tracking

### Additional Optimizations
- Removed custom stringsBuilder (replaced with strings.Builder)
- Extracted shared ParsePagination helper
- Removed unnecessary defensive copy in enginePoolAdapter
- Simplified getDrainStatus nil checks

### Architecture
```
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   internal/admin     โ”‚      โ”‚ internal/server/admin      โ”‚
โ”‚   (CLI Admin)       โ”‚      โ”‚   (Webhook Admin)          โ”‚
โ”‚   Bearer Token      โ”‚      โ”‚   API Key                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
           โ”‚                               โ”‚
           โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                      โ–ผ
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚   internal/adminapi      โ”‚
        โ”‚   (Shared Auth Domain)   โ”‚
        โ”‚   โ€ข AuthMiddleware       โ”‚
        โ”‚   โ€ข AuthMode enum        โ”‚
        โ”‚   โ€ข ParsePagination      โ”‚
        โ”‚   โ€ข Error utilities      โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
```

Resolves hrygo#331
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.

1 participant