Closes the gap that made section 20.1 ownership advisory. The service could refuse anonymous callers but could not tell two publishers apart, so a closed namespace could be protected and never attributed. Follows DR-3, resolved 2026-07-10: app-local accounts, with platform OIDC demand-gated on client SSO requests, instance consolidation, or local-account toil across more than two apps. None of those triggers has fired here, so this is deliberately not OIDC. Tokens rather than accounts because a registry is consumed by CLIs and agents — no browser, no session, no UI to log into, and a login surface nothing uses is a liability. The whole authentication boundary stays in auth.py, so contract section 2.3 is met and a later OIDC switch is bounded rather than a search. The properties that matter are the ones about what a credential cannot do: - tokens are stored hashed, because a registry that can print its own credentials back is one database read away from impersonating every publisher it knows, and are shown once at creation; - an unknown token and a wrong token get the same answer, so a caller cannot enumerate which tokens exist; - a publisher cannot mint publishers — that would be an administrator with extra steps, and revoking one would no longer revoke what it could do; - the operator token publishes but owns nothing, so it is a bootstrap path rather than an identity that can hold a namespace; - a closed namespace with no owner recorded admits nobody, including the operator: reading a missing owner as "anyone" would invert the point of closing it; - revocation is a timestamp, not a delete, so what someone published stays attributed to them after their credential is withdrawn. Migration 0003 adds publishers and index_entries.published_by. The attribution is a name rather than a foreign key, so deleting a publisher cannot erase the history of what they published. Service tests 49 -> 61. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
25 lines
623 B
TOML
25 lines
623 B
TOML
[build-system]
|
|
requires = ["hatchling"]
|
|
build-backend = "hatchling.build"
|
|
|
|
[project]
|
|
name = "canned-prompts-service"
|
|
version = "0.2.0"
|
|
description = "Hosted registry and index service for Canned Prompt Format packages"
|
|
requires-python = ">=3.12"
|
|
dependencies = [
|
|
"fastapi>=0.115.0",
|
|
"uvicorn[standard]>=0.32.0",
|
|
"sqlalchemy>=2.0.0",
|
|
"alembic>=1.14.0",
|
|
"pydantic>=2.10.0",
|
|
"pydantic-settings>=2.7.0",
|
|
"psycopg[binary]>=3.2.0",
|
|
"pyyaml>=6.0.3",
|
|
]
|
|
|
|
[project.optional-dependencies]
|
|
dev = ["pytest>=8", "httpx>=0.28.0"]
|
|
|
|
[tool.hatch.build.targets.wheel]
|
|
packages = ["src/canned_prompts_service"]
|