feat: forward X-API-Key header from Next.js proxy routes to ML service
All 12 Next.js API routes that proxy requests to the ML service (INFERENCE_API_URL / localhost:8001) now include the X-API-Key header read from process.env.API_KEY. Affected routes: - /api/predict - /api/predict/batch - /api/model/info - /api/model/load - /api/training/start - /api/training/runs - /api/training/runs/[run_id] (DELETE) - /api/training/dataset-info - /api/training/active - /api/training/build-dataset - /api/patterns/available - /api/patterns/detect Marks task 3.3 as complete in openspec/changes/code-review-fix/tasks.md. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5f569d9134
commit
4a3e4a48ba
13 changed files with 13 additions and 9 deletions
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
- [x] 3.1 `[sonnet]` Create `src/middleware.ts` with API key auth middleware: read `API_KEY` env var, check `X-API-Key` header on all `/api/*` routes except `/api/health`, return 401 if invalid
|
||||
- [x] 3.2 `[sonnet]` Add FastAPI `Depends()` API key dependency in `services/ml/app/main.py`: read `API_KEY` env var, check `X-API-Key` header, exempt `/health` endpoint
|
||||
- [ ] 3.3 `[sonnet]` Update all Next.js proxy routes to forward `X-API-Key` header to ML service
|
||||
- [x] 3.3 `[sonnet]` Update all Next.js proxy routes to forward `X-API-Key` header to ML service
|
||||
- [ ] 3.4 `[haiku]` Add `API_KEY` to `.env.example` with placeholder value and instructions
|
||||
|
||||
## 4. API Route Hardening (Next.js)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ export async function GET(request: NextRequest) {
|
|||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-API-Key': process.env.API_KEY || '',
|
||||
},
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export async function POST(request: NextRequest) {
|
|||
|
||||
const response = await fetch(`${INFERENCE_API_URL}/model/load`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.API_KEY || '' },
|
||||
body: JSON.stringify(body),
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export async function GET(_request: NextRequest) {
|
|||
try {
|
||||
const response = await fetch(`${INFERENCE_API_URL}/patterns/available`, {
|
||||
method: 'GET',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.API_KEY || '' },
|
||||
signal: controller.signal,
|
||||
});
|
||||
clearTimeout(timeoutId);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export async function POST(request: NextRequest) {
|
|||
|
||||
const response = await fetch(`${INFERENCE_API_URL}/patterns/detect`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.API_KEY || '' },
|
||||
body: JSON.stringify(body),
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ export async function POST(request: NextRequest) {
|
|||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-API-Key': process.env.API_KEY || '',
|
||||
},
|
||||
body: JSON.stringify(body),
|
||||
signal: controller.signal,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ export async function POST(request: NextRequest) {
|
|||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-API-Key': process.env.API_KEY || '',
|
||||
},
|
||||
body: JSON.stringify(body),
|
||||
signal: controller.signal,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export async function GET(_request: NextRequest) {
|
|||
try {
|
||||
const response = await fetch(`${INFERENCE_API_URL}/training/active`, {
|
||||
method: 'GET',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.API_KEY || '' },
|
||||
signal: controller.signal,
|
||||
});
|
||||
clearTimeout(timeoutId);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export async function POST() {
|
|||
try {
|
||||
const response = await fetch(`${INFERENCE_API_URL}/training/build-dataset`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.API_KEY || '' },
|
||||
signal: controller.signal,
|
||||
});
|
||||
clearTimeout(timeoutId);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export async function GET(_request: NextRequest) {
|
|||
try {
|
||||
const response = await fetch(`${INFERENCE_API_URL}/training/dataset-info`, {
|
||||
method: 'GET',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.API_KEY || '' },
|
||||
signal: controller.signal,
|
||||
});
|
||||
clearTimeout(timeoutId);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ export async function DELETE(
|
|||
try {
|
||||
const response = await fetch(`${INFERENCE_API_URL}/training/runs/${run_id}`, {
|
||||
method: 'DELETE',
|
||||
headers: { 'X-API-Key': process.env.API_KEY || '' },
|
||||
signal: controller.signal,
|
||||
});
|
||||
clearTimeout(timeoutId);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export async function GET(_request: NextRequest) {
|
|||
try {
|
||||
const response = await fetch(`${INFERENCE_API_URL}/training/runs`, {
|
||||
method: 'GET',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.API_KEY || '' },
|
||||
signal: controller.signal,
|
||||
});
|
||||
clearTimeout(timeoutId);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export async function POST(request: NextRequest) {
|
|||
|
||||
const response = await fetch(`${INFERENCE_API_URL}/training/start`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.API_KEY || '' },
|
||||
body: JSON.stringify(body),
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue