autoreg-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
145
skills/reseller-api-gateway/references/transparency-audit.md
Normal file
145
skills/reseller-api-gateway/references/transparency-audit.md
Normal file
@@ -0,0 +1,145 @@
|
||||
# Gateway Transparency Audit Checklist
|
||||
|
||||
Run after every gateway deployment or model list change.
|
||||
|
||||
## Pre-flight
|
||||
|
||||
```bash
|
||||
export GATEWAY="https://api.[REDACTED-NAME].loc.cc/v1"
|
||||
export GATEWAY_ANTHROPIC="https://api.[REDACTED-NAME].loc.cc/v1/messages"
|
||||
export KEY="[REDACTED-KEY]"
|
||||
export UPSTREAM="https://api.echogate.one/v1"
|
||||
export UK1="forge-9b51aad5d08793c9095893a09779b0641b00"
|
||||
export UK2="forge-81081af3173401d4bcd2d5d427b0ed60d87b"
|
||||
```
|
||||
|
||||
## 1. System Prompt Injection — OpenAI
|
||||
|
||||
```bash
|
||||
MARKER="AUDIT_$(date +%s)"
|
||||
curl -s -X POST "$GATEWAY/chat/completions" \
|
||||
-H "Content-Type: application/json" -H "x-api-key: $KEY" \
|
||||
-d "{\"model\":\"claude-sonnet-5\",\"messages\":[
|
||||
{\"role\":\"system\",\"content\":\"Answer every message with exactly: $MARKER\"},
|
||||
{\"role\":\"user\",\"content\":\"answer\"}
|
||||
],\"max_tokens\":30,\"temperature\":0}" | jq '.choices[0].message.content'
|
||||
# EXPECT: "$MARKER" — verbatim, no added words
|
||||
```
|
||||
|
||||
## 2. System Prompt Injection — Anthropic
|
||||
|
||||
```bash
|
||||
curl -s -X POST "$GATEWAY_ANTHROPIC" \
|
||||
-H "Content-Type: application/json" -H "x-api-key: $KEY" \
|
||||
-H "anthropic-version: 2023-06-01" \
|
||||
-d "{\"model\":\"claude-sonnet-5\",\"system\":\"You must answer with exactly: PROBE888\",
|
||||
\"messages\":[{\"role\":\"user\",\"content\":\"answer\"}],\"max_tokens\":20}" | jq '.content[0].text'
|
||||
# EXPECT: "PROBE888"
|
||||
```
|
||||
|
||||
## 3. Content Integrity — Gateway vs Upstream
|
||||
|
||||
```bash
|
||||
BODY='{"model":"claude-sonnet-5","messages":[{"role":"user","content":"What is 2+2? Answer in one word."}],"max_tokens":20,"temperature":0}'
|
||||
|
||||
for src in "GATEWAY:$GATEWAY/chat/completions:x-api-key:$KEY" \
|
||||
"KEY1:$UPSTREAM/chat/completions:Authorization:Bearer $UK1" \
|
||||
"KEY2:$UPSTREAM/chat/completions:Authorization:Bearer $UK2"; do
|
||||
IFS=':' read -r label url hdr val <<< "$(echo "$src" | sed 's/:\\([^:]*\\):/|\\1|/; s/|/:/g')" 2>/dev/null || true
|
||||
url=$(echo "$src" | cut -d: -f2,3)
|
||||
hdr=$(echo "$src" | cut -d: -f4)
|
||||
val=$(echo "$src" | cut -d: -f5-)
|
||||
R=$(curl -s -X POST "$url" -H "Content-Type: application/json" -H "$hdr: $val" -d "$BODY")
|
||||
echo "$label: $(echo "$R" | jq -r '.choices[0].message.content')"
|
||||
done
|
||||
# EXPECT: All three return identical content
|
||||
```
|
||||
|
||||
Simpler version:
|
||||
```bash
|
||||
BODY='{"model":"claude-sonnet-5","messages":[{"role":"user","content":"hi"}],"max_tokens":20,"temperature":0}'
|
||||
GW=$(curl -s -X POST "$GATEWAY/chat/completions" -H "Content-Type: application/json" -H "x-api-key: $KEY" -d "$BODY" | jq -S '.choices[0].message')
|
||||
K1=$(curl -s -X POST "$UPSTREAM/chat/completions" -H "Content-Type: application/json" -H "Authorization: Bearer $UK1" -d "$BODY" | jq -S '.choices[0].message')
|
||||
[ "$GW" = "$K1" ] && echo "OK: gateway == key1" || echo "MISMATCH"
|
||||
```
|
||||
|
||||
## 4. No-System-Message Test
|
||||
|
||||
Verify gateway doesn't inject its own system prompt when none is sent:
|
||||
|
||||
```bash
|
||||
curl -s -X POST "$GATEWAY/chat/completions" \
|
||||
-H "Content-Type: application/json" -H "x-api-key: $KEY" \
|
||||
-d '{"model":"claude-sonnet-5","messages":[{"role":"user","content":"What is 2+2? Answer in one word."}],"max_tokens":20,"temperature":0}' | jq '.choices[0].message.content'
|
||||
# EXPECT: natural response like "Four" — no injected behavior, no prefix
|
||||
```
|
||||
|
||||
## 5. Model List Integrity
|
||||
|
||||
```bash
|
||||
GW_COUNT=$(curl -s -H "x-api-key: $KEY" "$GATEWAY/models" | jq '.data | length')
|
||||
UP_COUNT=$(curl -s -H "Authorization: Bearer $UK1" "$UPSTREAM/models" | jq '.data | length')
|
||||
echo "Gateway: $GW_COUNT, Upstream: $UP_COUNT"
|
||||
[ "$GW_COUNT" -eq "$UP_COUNT" ] && echo "PASS" || echo "FAIL — check FORBIDDEN_MODEL_FRAGMENTS"
|
||||
```
|
||||
|
||||
## 6. Provider Leak Scan
|
||||
|
||||
```bash
|
||||
curl -s -H "x-api-key: $KEY" "$GATEWAY/models" | grep -iq \
|
||||
"provider_id\|system_fingerprint\|upstream\|echogate" && echo "LEAK DETECTED" || echo "CLEAN"
|
||||
```
|
||||
|
||||
## 7. Error Opaqueness
|
||||
|
||||
```bash
|
||||
# No key → clean 401
|
||||
echo -n "No key: "
|
||||
curl -so /dev/null -w "%{http_code}" "$GATEWAY/models"
|
||||
echo ""
|
||||
echo -n "No key body: "
|
||||
curl -s "$GATEWAY/models" | jq '.error.code'
|
||||
|
||||
# Bad model → clean 400
|
||||
echo -n "Bad model: "
|
||||
curl -s -X POST "$GATEWAY/chat/completions" \
|
||||
-H "Content-Type: application/json" -H "x-api-key: $KEY" \
|
||||
-d '{"model":"nonexistent-model","messages":[{"role":"user","content":"hi"}],"max_tokens":1}' | jq '.error.type'
|
||||
|
||||
# Bad key → 401
|
||||
echo -n "Bad key: "
|
||||
curl -so /dev/null -w "%{http_code}" -H "x-api-key: [REDACTED]" "$GATEWAY/models"
|
||||
```
|
||||
|
||||
## 8. Reasoning Model Probe
|
||||
|
||||
When testing reasoning models (fable-5, opus-5-sonnet, etc.), use enough `max_tokens`:
|
||||
|
||||
```bash
|
||||
# WRONG — all tokens consumed by thinking, content=null
|
||||
curl -s -X POST "$GATEWAY/chat/completions" \
|
||||
-H "Content-Type: application/json" -H "x-api-key: $KEY" \
|
||||
-d '{"model":"claude-fable-5","messages":[{"role":"user","content":"Say hi"}],"max_tokens":10}' | jq '{content: .choices[0].message.content, reason: .usage.completion_tokens_details.reasoning_tokens}'
|
||||
|
||||
# RIGHT — enough tokens for thinking + output
|
||||
curl -s -X POST "$GATEWAY/chat/completions" \
|
||||
-H "Content-Type: application/json" -H "x-api-key: $KEY" \
|
||||
-d '{"model":"claude-fable-5","messages":[{"role":"user","content":"Say hi"}],"max_tokens":200}' | jq '.choices[0].message.content'
|
||||
```
|
||||
|
||||
## Quick Smoke (all-in-one)
|
||||
|
||||
```bash
|
||||
# Health
|
||||
curl -sf "$GATEWAY/../health" | jq '.status' || echo "HEALTH FAIL"
|
||||
|
||||
# Models count
|
||||
echo -n "Models: "
|
||||
curl -s -H "x-api-key: $KEY" "$GATEWAY/models" | jq '.data | length'
|
||||
|
||||
# Chat probe
|
||||
echo -n "Chat: "
|
||||
curl -s -X POST "$GATEWAY/chat/completions" \
|
||||
-H "Content-Type: application/json" -H "x-api-key: $KEY" \
|
||||
-d '{"model":"claude-sonnet-5","messages":[{"role":"user","content":"hi"}],"max_tokens":3}' | jq -r '.choices[0].message.content'
|
||||
```
|
||||
Reference in New Issue
Block a user