Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ See README.md for complete `.env` setup. Key variables:
- **Neo4j**: `NEO4J_URI`, `NEO4J_USER`, `NEO4J_PASSWORD`
- **Storage**: `OBJECT_STORAGE_URI`, `MINIO_ACCESS_KEY`, `MINIO_SECRET_KEY`, `MINIO_OBJECTS_BUCKET_NAME`
- **Authorization**: `RESTRICTED_BRANCH_NAME` - branch containing restricted blobs
- **Optional**: `POSTHOG_HOST`, `POSTHOG_PROJECT_API_KEY`, `NODE_ENV`, `ALLOWED_ORIGINS`, `SENSITIVE_REGISTRY_VALUES`
- **Optional**: `POSTHOG_HOST`, `POSTHOG_PROJECT_API_KEY`, `NODE_ENV`, `SENSITIVE_REGISTRY_VALUES`

## Testing Strategy
- Jest 30 with ts-jest for TypeScript support
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ POSTHOG_PROJECT_API_KEY=

# Optional - Environment
NODE_ENV=development
ALLOWED_ORIGINS=https://oswatcher.github.io,http://127.0.0.1:8080

# Optional - Registry Filtering
# Unused unless the plugin commented out in src/index.ts is re-enabled
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/access-restrictions.md
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ When adding new restrictions:
| Rate Limiting | Middleware | All endpoints | Block (429) | Hardcoded (100/min) | Active |
| Result Set Limits | GraphQL Schema | All paginated queries | Limit to 5000 | `@limit` directive | Active |
| Mutations | GraphQL Schema | Write operations | Block (disabled) | `@mutation(operations: [])` | Active |
| CORS | Middleware | All endpoints | Block | `ALLOWED_ORIGINS` | Active |
| CORS | Middleware | All endpoints | Allow any origin | None | Open by design (no credentials are ever sent) |

---

Expand Down
25 changes: 9 additions & 16 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ import { createRestRouter } from "./rest-routes.js";
// import { filterSensitiveRegistryValues } from "./registry-response-filter.js";
import express, { Request, Response } from "express";
import { expressMiddleware } from "@as-integrations/express5";
// The API is public, read-only and unauthenticated: no cookies, no
// Authorization header, nothing a browser could be tricked into attaching. An
// origin allow-list therefore protects nothing (curl ignores CORS entirely)
// while breaking every local frontend and third-party tool. Access control
// that does matter is enforced server-side: rate limiting and restricted-branch
// filtering.
import cors from "cors";
import axios from "axios";
import { createServer } from "http";
Expand Down Expand Up @@ -61,10 +67,6 @@ const env = cleanEnv(process.env, {
default: "development",
desc: "Node environment",
}),
ALLOWED_ORIGINS: str({
default: "https://oswatcher.github.io,http://127.0.0.1:8080",
desc: "Comma-separated list of allowed CORS origins",
}),
SENSITIVE_REGISTRY_VALUES: str({
default: "",
desc: "Comma-separated list of sensitive registry value names to redact",
Expand Down Expand Up @@ -329,10 +331,7 @@ async function main() {
if (isProduction && env.POSTHOG_PROJECT_API_KEY) {
app.use(
"/events",
cors({
origin: env.ALLOWED_ORIGINS.split(","),
credentials: true,
}),
cors(),
express.raw({ type: "*/*", limit: "10mb" }),
async (req: Request, res: Response) => {
try {
Expand Down Expand Up @@ -378,10 +377,7 @@ async function main() {
// Blob REST API - mounted before GraphQL
app.use(
"/blob",
cors({
origin: env.ALLOWED_ORIGINS.split(","),
credentials: true,
}),
cors(),
createRateLimit(100, 60000), // 100 requests per minute
express.json({ limit: "1mb" }),
createRestRouter(
Expand All @@ -397,10 +393,7 @@ async function main() {
// Apply middleware
app.use(
"/graphql",
cors({
origin: env.ALLOWED_ORIGINS.split(","),
credentials: true,
}),
cors(),
createRateLimit(100, 60000), // 100 requests per minute
express.json({ limit: "1mb" }),
expressMiddleware(server, {
Expand Down
Loading