feat: implement raycast backend

This commit is contained in:
hh
2026-05-19 21:06:01 +02:00
parent 221e660c5c
commit 757065f21c
16 changed files with 1415 additions and 31 deletions
+105
View File
@@ -0,0 +1,105 @@
"""Bearer-token verification (Phase 1.3 — in-memory only).
Phase 4 will replace this with a DB-backed store (PRD §8 ``tokens``
table, Argon2 hashes, scopes, ``last_used_at`` batching). Until then,
frontends authenticate callers against an in-memory ``{value: name}``
dict seeded from the ``BOOTSTRAP_TOKENS`` env var.
Format::
BOOTSTRAP_TOKENS=cursor:s3cret,laptop:hunter2
The *name* side is for audit lines — :py:meth:`TokenStore.verify`
returns it on hit so callers can attribute the request without
exposing the raw secret. ``None`` means "no such token"; callers
turn that into 401.
This module deliberately knows nothing about HTTP frameworks — it
takes a raw token (or the verbatim ``Authorization`` header value)
and returns a name-or-None. Frontends own the response shape.
"""
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from collections.abc import Mapping
class TokenStoreError(ValueError):
"""Malformed ``BOOTSTRAP_TOKENS`` value."""
class TokenStore:
"""Constant-time-ish bearer verification over a static name→value map.
The store is keyed by value internally (``verify`` lookup is O(1))
but constructed from a name→value mapping because that's how the
user thinks about it — one human-readable label per caller.
"""
__slots__ = ("_by_value",)
def __init__(self, tokens: Mapping[str, str]) -> None:
by_value: dict[str, str] = {}
for name, value in tokens.items():
if not name or not value:
msg = f"empty name or value in token map (name={name!r})"
raise TokenStoreError(msg)
if value in by_value:
msg = (
f"duplicate token value for names "
f"{by_value[value]!r} and {name!r}"
)
raise TokenStoreError(msg)
by_value[value] = name
self._by_value = by_value
@classmethod
def from_env(cls, raw: str) -> TokenStore:
"""Parse ``name1:value1,name2:value2`` (the ``BOOTSTRAP_TOKENS`` form)."""
tokens: dict[str, str] = {}
for chunk in raw.split(","):
entry = chunk.strip()
if not entry:
continue
name, sep, value = entry.partition(":")
if not sep:
msg = f"token entry missing ':' separator: {entry!r}"
raise TokenStoreError(msg)
name, value = name.strip(), value.strip()
if name in tokens:
msg = f"duplicate token name: {name!r}"
raise TokenStoreError(msg)
tokens[name] = value
return cls(tokens)
def verify(self, token: str | None) -> str | None:
"""Return the token's name if known, else ``None``."""
if not token:
return None
return self._by_value.get(token)
def verify_bearer(self, authorization: str | None) -> str | None:
"""Strip the ``Bearer`` prefix (case-insensitive) then verify.
Accepts a bare token too — Cursor's MCP transport sometimes
passes the raw value via ``?token=`` and reuses the same
verifier; treating an unprefixed header as a bare token keeps
both call sites on one method.
"""
if not authorization:
return None
head, sep, rest = authorization.partition(" ")
token = rest.strip() if sep and head.lower() == "bearer" else authorization
return self.verify(token)
def __len__(self) -> int:
return len(self._by_value)
def __bool__(self) -> bool:
return bool(self._by_value)
__all__ = ["TokenStore", "TokenStoreError"]