Skip to content
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
3fd7868
fix: address CodeQL security findings
suguanYang May 1, 2026
a2c36d8
refactor: remove unused api key hash version
suguanYang May 4, 2026
b77b01d
refactor: remove database health endpoints
suguanYang May 5, 2026
be959c5
refactor: extract pinned outbound url helpers
suguanYang May 5, 2026
4e5979f
refactor: move outbound helpers to shared utils
suguanYang May 5, 2026
4c13370
refactor: remove database health routes
suguanYang May 5, 2026
73ca3cc
ci: add codeql scanning workflow
suguanYang May 5, 2026
20214a7
fix: pin outbound url downloads
suguanYang May 5, 2026
e9d3a39
fix: simplify api key hashing
suguanYang May 6, 2026
fd97cf6
refactor: simplify api key token narrowing
suguanYang May 6, 2026
0edceb9
refactor: separate api key auth cache from rate limits
suguanYang May 6, 2026
132bd2b
refactor: centralize api key identity lookup
suguanYang May 6, 2026
4d821d9
refactor: invalidate tier identity caches in tier service
suguanYang May 6, 2026
6573836
refactor: keep api key cache auth only
suguanYang May 6, 2026
9446b79
refactor: rename user tier cache methods
suguanYang May 6, 2026
f814d82
revert: restore api key and local bootstrap changes
suguanYang May 6, 2026
5cd99c6
refactor: split api key and tier identity caches
suguanYang May 6, 2026
d69a453
refactor: remove unused health check endpoints and related tests
suguanYang May 6, 2026
1478552
refactor: separate api key and tier caches
suguanYang May 6, 2026
c9b7852
test: configure api contract import paths
suguanYang May 6, 2026
ebbc362
test: lazy import api service contracts
suguanYang May 6, 2026
c1008cc
refactor: use keyed api key hashes
suguanYang May 6, 2026
928bb84
chore: suppress intentional api key lookup hash alert
suguanYang May 6, 2026
18ce9a9
chore: ignore api key hash helper in codeql
suguanYang May 6, 2026
228e3db
refactor: remove unnecessary API key auth state checks in rate limit …
suguanYang May 6, 2026
114271d
refactor: remove TYPE_CHECKING imports and streamline type annotation…
suguanYang May 6, 2026
79e172c
refactor: clean up configuration files and remove unused variables
suguanYang May 6, 2026
1609907
refactor: update README and scripts for local development setup; enab…
suguanYang May 6, 2026
f67ad0f
refactor: update CodeQL config and remove obsolete test files; stream…
suguanYang May 6, 2026
abcc9dd
refactor: update README and environment files for API standalone mode…
suguanYang May 6, 2026
ac5b524
refactor: replace outbound URL validation with HTTP URL validation ac…
suguanYang May 7, 2026
6b2079c
fix: update environment assertion in version payload test to production
suguanYang May 7, 2026
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
5 changes: 5 additions & 0 deletions .github/codeql/codeql-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: "Knowhere CodeQL config"

paths-ignore:
- apps/api/scripts/**
- packages/shared-python/shared/utils/api_keys.py
46 changes: 46 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: CodeQL

on:
pull_request:
branches:
- main
- staging

permissions:
contents: read
security-events: write
actions: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- name: Checkout code
uses: actions/checkout@v6
with:
persist-credentials: false

- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: python
queries: security-extended,security-and-quality
config-file: ./.github/codeql/codeql-config.yml

- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.11"

- name: Autobuild
uses: github/codeql-action/autobuild@v4

- name: Perform CodeQL analysis
uses: github/codeql-action/analyze@v4
42 changes: 17 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ knowhere-api/
- Python 3.11+
- `uv`
- Docker with `docker compose`
- a local Chrome or Chromium driver if you plan to run document layout parsing
flows

## Configuration

Expand All @@ -61,51 +59,45 @@ cp apps/worker/.env.example apps/worker/.env

- database and Redis connection settings
- S3-compatible storage credentials
- `SECRET_KEY`
- `USERS_DATA_PATH`
- `DS_KEY`
- any optional LLM, billing, or webhook providers you want to enable

The example files default to the open-source/self-hosted behavior:
These settings control the local startup mode:

- `API_STANDALONE_MODE_ENABLED=false` for the combined dashboard + API flow, where
the dashboard initializes Better Auth tables before API migrations.
- `BILLING_ENABLED=false`, so Stripe and credit deduction are not required.
- `RATE_LIMIT_ENABLED=false` for local/self-hosted convenience; set it to
`true` when you want API rate limits enforced.
- `BILLING_ENABLED` controls Stripe and credit deduction.
- `RATE_LIMIT_ENABLED` controls API rate limit enforcement.

For API-only development without the dashboard, set `API_STANDALONE_MODE_ENABLED=true`,
run API migrations, then create an API-only user/key:

```bash
cd apps/api
uv run --python 3.11 python -m alembic upgrade heads
uv run --python 3.11 python scripts/init_user.py --email you@example.com
```

If you plan to use the dashboard, start the combined self-hosted stack and
register through the dashboard instead of using `scripts/init_user.py`.
For API-only development without the dashboard, set
`API_STANDALONE_MODE_ENABLED=true` in `apps/api/.env`.

4. Start the local infrastructure stack:

```bash
./deploy/local-dev/start-dev.sh
```

If you also want the helper to initialize the local API user state, rerun it
with `--init-user`:
5. Start the API and worker in separate terminals:

```bash
./deploy/local-dev/start-dev.sh --init-user
cd apps/api && uv run uvicorn main:app --host 0.0.0.0 --port 5005 --reload
cd apps/worker && uv run python worker.py
```

5. Start the API and worker in separate terminals:
The API runs migrations during startup.

For API-only development without the dashboard, create an API-only user/key
after the API service starts:

```bash
cd apps/api && uv run main.py
cd apps/worker && uv run worker.py
cd apps/api
uv run --python 3.11 python scripts/init_user.py --email you@example.com
```

If you plan to use the dashboard, register through the dashboard instead of
using `scripts/init_user.py`.

## Quality Checks

Run lint checks from the repository root:
Expand Down
64 changes: 6 additions & 58 deletions apps/api/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# Required for specific features:
# - alternate object storage callbacks
# - webhooks and async callback delivery
# - billing, email, analytics, and dashboard auth providers
# - billing and analytics
# - alternate parsing providers
#
# Optional or development-only values can stay empty unless you need the
Expand All @@ -19,20 +19,13 @@
# Required for local startup: application runtime
ENVIRONMENT=development
APP_ENV=
DEBUG=true
LOG_LEVEL=INFO
APP_TITLE=Knowhere API
APP_VERSION=1.0.0
APP_DESCRIPTION=Document ingestion, retrieval, and MCP backend
SECRET_KEY=replace-with-a-long-random-secret
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=10080
INTERNAL_DASHBOARD_ENDPOINT=http://localhost:3000
API_STANDALONE_MODE_ENABLED=false
TMP_PATH=/tmp/knowhere
FONT_PATH=/usr/share/fonts
CHROMEDRIVER_PATH=/usr/bin/chromedriver
USERS_DATA_PATH=/tmp/knowhere-users

# Optional or development-only: observability and local dashboard wiring
LOGFIRE_TOKEN=
Expand All @@ -46,7 +39,7 @@ DB_SSL_MODE=disable
# DB_SSL_ROOT_CERT=/path/to/ca-cert.pem

# Required for local startup: Redis / Celery
RATE_LIMIT_ENABLED=false
RATE_LIMIT_ENABLED=true
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
Expand All @@ -57,7 +50,6 @@ BROKER_POOL_LIMIT=10
# Required for local startup: S3-compatible storage
S3_TYPE=s3
S3_BUCKET_NAME=knowhere-uploads
S3_UPLOADS_BUCKET=knowhere-uploads
S3_RESULTS_BUCKET=knowhere-results
S3_ACCESS_KEY_ID=test
S3_SECRET_ACCESS_KEY=test
Expand All @@ -68,7 +60,6 @@ S3_REGION=us-west-1
S3_USE_SSL=false
S3_ADDRESSING_STYLE=path
S3_WEBHOOK_AUTH_TOKEN=replace-with-a-shared-secret
SNS_SIGNATURE_VERIFICATION=true

# Required for specific features: OSS settings
OSS_ENDPOINT=
Expand All @@ -90,7 +81,6 @@ ALI_SDK_MAX_RETRIES=3
ALI_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
ARK_API_KEY=
ARK_URL=https://ark.cn-beijing.volces.com/api/v3/chat/completions
EMBEDDING_MODEL=text-embedding-v4
NORMOL_MODEL=deepseek-chat
HIERARCHY_LLM_MODEL=qwen3.6-flash
IMAGE_MODEL=qwen3.5-flash
Expand All @@ -99,58 +89,23 @@ IMAGE_MODEL_MAX=qwen3.5-flash
# File handling defaults
SUPPORTED_EXTENSIONS=.doc,.docx,.pdf,.txt,.xls,.xlsx,.csv,.pptx,.jpg,.jpeg,.png,.md
MAX_FILE_SIZE=104857600
MAX_IMAGE_SIZE=10485760
MIN_CONFIDENCE_THRESHOLD=0.05
HIGH_IOU_THRESHOLD=0.9
DEFAULT_EMBEDDING_DIM=1024
DEFAULT_TOP_K=5
DEFAULT_BATCH_SIZE=32
DEFAULT_EPOCHS=3
DEFAULT_THRESHOLD=0.5

# Required for specific features: webhooks and callbacks
WEBHOOK_SIGNING_SECRET=
WEBHOOK_MASTER_KEY=
QSTASH_TOKEN=
QSTASH_CALLBACK_BASE_URL=https://api.example.com/api/v1
QSTASH_MAX_RETRIES=5
# QSTASH_CURRENT_SIGNING_KEY=
# QSTASH_NEXT_SIGNING_KEY=

# Required for specific features: billing and notifications
BILLING_ENABLED=false
# Required for specific features: billing and analytics
BILLING_ENABLED=true
STRIPE_SECRET_KEY=
STRIPE_PUBLISHABLE_KEY=
STRIPE_WEBHOOK_SECRET=
RESEND_API_KEY=
RESEND_FROM_EMAIL=noreply@example.com
RESEND_FROM_NAME=Knowhere
RESEND_MAX_RETRIES=3
RESEND_RETRY_DELAY=1.0
RESEND_TEMPLATE_WELCOME=
RESEND_TEMPLATE_PURCHASE_CONFIRMATION=
RESEND_TEMPLATE_JOB_COMPLETION=
RESEND_TEMPLATE_JOB_FAILURE=
RESEND_TEMPLATE_WELCOME_ENABLED=false
RESEND_TEMPLATE_PURCHASE_CONFIRMATION_ENABLED=false
RESEND_TEMPLATE_JOB_COMPLETION_ENABLED=false
RESEND_TEMPLATE_JOB_FAILURE_ENABLED=false
MOESIF_APPLICATION_ID=
NEXT_PUBLIC_POSTHOG_KEY=
NEXT_PUBLIC_POSTHOG_HOST=https://app.posthog.com
FREE_PLAN_INITIAL_CREDITS=5
FRONTEND_URL=http://localhost:3000

# Required for specific features: dashboard and auth providers
USERS_VERIFY_TOKEN_SECRET=
USERS_RESET_PASSWORD_TOKEN_SECRET=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
APPLE_CLIENT_ID=
APPLE_CLIENT_SECRET=

# Required for specific features: parsing providers
MINERU_API_KEYS=
MINERU_URL=https://mineru.net/api/v4
Expand All @@ -163,13 +118,6 @@ ILOVEAPI_SECRET_KEY=
ILOVEAPI_BASE_URL=https://api.ilovepdf.com/v1
ILOVEAPI_TIMEOUT=120

# Optional or development-only: compatibility fields kept for retained legacy code paths
# Legacy parser compatibility fields.
ALL_DF_COLS=content,path,type,length,keywords,summary,know_id,tokens,connectto,addtime,page_nums
DEFAULT_FOLDERS=Supplementary_Files,Temporary_Files,templates,images,fragments
KB_TERM=KB_DATA
KB_VEC_TERM=KB_VECS
META_PATH=app/core/config/Meta_setting.csv
CONFIG_PATH=app/core/config/config.txt
PATH_IMAGE_PATTERN=.*\.(png|jpe?g|gif)$
IMG_TBL_PATTERN=\[(?:images|tables)/[^\]]+\]
SPLIT_CHAR=/
SPLIT_CHAR=-->
4 changes: 2 additions & 2 deletions apps/api/alembic/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def run_with_connection(connection: Connection) -> None:
return

if isinstance(configured_connection, Engine):
with configured_connection.connect() as connection:
with configured_connection.begin() as connection:
run_with_connection(connection)
return

Expand All @@ -149,7 +149,7 @@ def run_with_connection(connection: Connection) -> None:
connect_args=ssl_connect_args,
)

with connectable.connect() as connection:
with connectable.begin() as connection:
run_with_connection(connection)


Expand Down
4 changes: 0 additions & 4 deletions apps/api/app/api/v1/api_v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
API v1 route registry.
"""

from app.api.v1 import health
from app.api.v1.routes import (
api_key,
documents,
Expand Down Expand Up @@ -59,9 +58,6 @@
qstash_callbacks.router, prefix="/webhooks", tags=["QStash Callbacks"]
)

# Health check
api_router.include_router(health.router, prefix="/health", tags=["Health"])

# Version info
api_router.include_router(version.router, tags=["Version"])

Expand Down
39 changes: 0 additions & 39 deletions apps/api/app/api/v1/health.py

This file was deleted.

Loading
Loading