ae67bff5a3
Self-hosted platform for building, testing, and shipping LangChain/LangGraph agents. Deep-agent sub-agents on the canvas, a live tracing/observability timeline, auto-provisioned built-in tools with import/export, per-environment tool variables, streamed evaluations, and per-user auth token forwarding.
45 lines
1.6 KiB
Python
45 lines
1.6 KiB
Python
"""api_keys: user_id + project_id (personal access tokens for MCP)
|
|
|
|
Adds two nullable columns to `api_keys` so a key can be a per-user Personal Access Token (PAT)
|
|
scoped to a single project - used to authenticate an individual over a project's MCP server as an
|
|
end_user. Existing (tenant, role) server-to-server keys leave both NULL and are unaffected.
|
|
|
|
Idempotent: each column is added only when absent, so this is safe whether the table was created
|
|
fresh by `create_all` (columns already present via the ORM) or predates the feature.
|
|
|
|
Revision ID: 0008_apikey_user_scope
|
|
Revises: 0007_tool_sets
|
|
Create Date: 2026-07-15
|
|
"""
|
|
import sqlalchemy as sa
|
|
from alembic import op
|
|
|
|
revision = "0008_apikey_user_scope"
|
|
down_revision = "0007_tool_sets"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def _cols(insp, table: str) -> set[str]:
|
|
return {c["name"] for c in insp.get_columns(table)} if table in insp.get_table_names() else set()
|
|
|
|
|
|
def upgrade() -> None:
|
|
insp = sa.inspect(op.get_bind())
|
|
existing = _cols(insp, "api_keys")
|
|
if "api_keys" not in insp.get_table_names():
|
|
return # fresh DBs build the column from the ORM; nothing to alter
|
|
if "user_id" not in existing:
|
|
op.add_column("api_keys", sa.Column("user_id", sa.String(36), nullable=True))
|
|
if "project_id" not in existing:
|
|
op.add_column("api_keys", sa.Column("project_id", sa.String(36), nullable=True))
|
|
|
|
|
|
def downgrade() -> None:
|
|
insp = sa.inspect(op.get_bind())
|
|
existing = _cols(insp, "api_keys")
|
|
if "project_id" in existing:
|
|
op.drop_column("api_keys", "project_id")
|
|
if "user_id" in existing:
|
|
op.drop_column("api_keys", "user_id")
|