Skip to content

Bug: generate_uri endpoint creates JWT tokens but does not persist app records to database #380

@Tyrannius

Description

@Tyrannius

Bug: generate_uri endpoint creates JWT tokens but does not persist app records to database

Another issue I just encountered. PLEASE CHECK BEFORE IMPLEMENTING.

Summary

The POST /local/generate_uri endpoint successfully generates JWT tokens and returns a morphik:// connection URI, but does not insert any record into the apps table in PostgreSQL. This makes every generated token immediately invalid, as the auth middleware looks up the app_id from the JWT in the apps table and rejects the request with "Invalid or revoked token" when no matching row is found.

Authentication is completely broken in the Docker image for self-hosted deployments.

Environment

  • Deployment: Docker (self-hosted)
  • Image: ghcr.io/morphik-org/morphik-core:latest
  • Database: pgvector/pgvector:pg16
  • Date observed: 2026-02-12

Steps to Reproduce

  1. Fresh install via install_docker.sh
  2. Configure .env with LOCAL_URI_PASSWORD and JWT_SECRET_KEY
  3. Start services with docker compose up -d
  4. Generate a connection URI:
curl -X POST http://localhost:8003/local/generate_uri \
  -d 'password_token=YOUR_LOCAL_URI_PASSWORD&name=testuser'

Response (200 OK):

{"uri":"morphik://testuser:eyJhbG...@0.0.0.0:8003"}
  1. Use the token from the URI:
TOKEN='eyJhbG...'
curl -X POST http://localhost:8003/documents/list_docs \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'

Response:

{"detail":"Invalid or revoked token"}
  1. Check the apps table:
SELECT * FROM apps;
-- Returns 0 rows

Root Cause

The generate_uri endpoint:

  1. Validates the password_token
  2. Creates a JWT with user_id, entity_id, app_id, and token_version
  3. Returns the URI with the token ✅
  4. Does NOT insert a corresponding row into the apps table

The auth middleware then:

  1. Decodes the JWT ✅
  2. Looks up app_id in the apps table → not found → rejects as "Invalid or revoked"

Additional Issues Found During Workaround Attempts

Manual INSERT fails due to type mismatch: The JWT embeds user_id as a plain string (e.g., "testuser"), but the apps table defines user_id as UUID type:

INSERT INTO apps (app_id, user_id, name, token_version, created_at)
VALUES ('ca5b4d2f-...', 'testuser', 'testuser', 0, NOW());
-- ERROR: invalid input syntax for type uuid: "testuser"

Even when using a synthetic UUID for user_id, the uri column has a NOT NULL constraint that generate_uri would need to populate:

INSERT INTO apps (app_id, user_id, name, token_version, created_at)
VALUES ('ca5b4d2f-...', 'a0000000-...', 'testuser', 0, NOW());
-- ERROR: null value in column "uri" violates not-null constraint

Even after satisfying all constraints with a manual INSERT, the token is still rejected — likely because the auth middleware compares the user_id from the JWT (string "testuser") against the UUID column and the types don't match.

Impact

  • All self-hosted Docker deployments cannot use token-based authentication
  • The only workaround is bypass_auth_mode = true, which disables all auth and multi-user isolation
  • The generate_uri endpoint returns 200 OK with a seemingly valid token, giving no indication that authentication will fail
  • This effectively makes the documented authentication workflow non-functional

Expected Behavior

generate_uri should atomically:

  1. Create the JWT token
  2. Insert a matching record into the apps table (with correct types for all columns)
  3. Only then return the URI to the caller

Workaround

Set bypass_auth_mode = true in morphik.toml and rely on network-level access control (firewall/VLAN) instead:

[auth]
bypass_auth_mode = true

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions