BeiBaiNian opened a new pull request, #191:
URL: https://github.com/apache/casbin-gateway/pull/191

   This PR is part of issue #179 "make a UI-first LLM API security gateway". 
Token management (milestone 1.3) is the core of the "security guardrails" 
selling point: it issues client-facing virtual keys (sk-xxx), enforces 
authentication, per-model permissions and rate limiting on the 1.2 unified 
endpoint /v1/chat/completions, and repays the plaintext-storage tech debt of 
Channel.ApiKey left over from 1.1 (AES encryption + one-time migration).
   
   # What changed
   
   - Added controllers/token.go: 5 CRUD APIs — GET /api/get-tokens (paginated), 
GET /api/get-token, POST /api/add-token, POST /api/update-token, POST 
/api/delete-token. On creation, the secret key is bcrypt-hashed; the plaintext 
key is returned exactly once in the creation response. List/detail responses 
only expose the SecretKeyPrefix mask — the key itself never leaves the DB.
   - Added object/token.go: Token model (owner+name composite primary key, 
following the object/site.go multi-tenant pattern) with SecretKeyHash (bcrypt), 
SecretKeyPrefix, ExpireTime (RFC3339, empty = never expires), AllowedModels 
([]string, JSON-serialized, empty = allow all), RateLimit (int, 0 = unlimited), 
Status. GetTokenBySecretKeyHash() compares bcrypt hashes across enabled tokens.
   - Added object/aes.go: EncryptApiKey/DecryptApiKey (AES-256-GCM, key from 
env/config). Channel.ApiKey and Token.SecretKey serve different purposes: the 
former must be forwarded in plaintext → reversible encryption; the latter is 
only compared → hash-only storage.
   - Modified object/channel.go: AddChannel/UpdateChannel AES-encrypt the API 
key before writing; TestChannelConnectivity and GetChannelByModel decrypt on 
read; added MigrateChannelApiKeys(), an idempotent migration (attempt 
decryption to detect plaintext, encrypt in place if needed) invoked from 
InitConfig after table creation, so keys written by 1.1 are upgraded without 
breaking the forwarding path the moment 1.3 merges.
   - Added object/rate_limit.go: CheckRateLimit in-memory limiter (sync.Map, 
fixed one-minute windows, lazy cleanup of stale entries; limit <= 0 disables 
limiting).
   - Modified controllers/proxy.go: ChatCompletions now runs authenticateToken 
first — extract Authorization: Bearer → GetTokenBySecretKeyHash bcrypt compare 
→ check Status/ExpireTime/AllowedModels/RateLimit, returning 401 
(missing/invalid token), 403 (disabled/expired/model not allowed) or 429 (rate 
limited) as appropriate.
   - Modified routers/router.go: registered the 5 /api/token routes.
   - Modified object/ormer.go: createTable() registers Sync2(new(Token)); 
InitConfig calls MigrateChannelApiKeys().
   - Frontend (same PR): added TokenListPage.js (list + creation modal: custom 
name, AllowedModels selectable from the union of existing channels' models, 
one-time plaintext key display with a one-click copy button), TokenEditPage.js 
(edit name/model permissions/rate limit/expire time/status; expire time stored 
as RFC3339 to match the backend time.Parse); backend/TokenBackend.js; menu 
routes in App.js; en/zh locale entries under the token namespace.
   
   # Verification
   
   - go vet ./... passed (fixed the call-site error caused by the 
TestChannelConnectivity signature change).
   - yarn run build passed.
   - Local UI testing: creating a token (custom name + model selection) works, 
the one-time key modal displays and the copy button works; the edit page's 
Expire Time now saves and re-displays correctly (fixed the DatePicker value 
always null and the non-RFC3339 dateString defects); list page styling aligns 
with ChannelListPage (pagination/loading/status tags/tooltips).
   - End-to-end auth chain (curl 401/403/429 states, AES migration DB 
verification) is deferred to the 1.6 integration milestone.
   
   # Note
   
   - This PR branches off the 1.2 branch (feat-proxy-1.2) and depends on it 
being merged; ship back-to-back with 1.2.
   - After 1.3 merges, /v1/chat/completions switches from unauthenticated to 
mandatory Bearer token auth — an intentional behavior change.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to