Commit Graph

1947 Commits

Author SHA1 Message Date
Jakub Zych
24cf6cd931 fix(pier): end only the revoked token's or client's MCP sessions and log the client address (B-WR-04, B-IN-04)
- pact.MCPSubjectChanged and pier.Event gain TokenID and ClientID; a
  narrowed revoked event closes only matching sessions and stateless servers
- cabana fires the admin token revoke with the token row id
- towel.WithClientIP/ClientIP; pier puts the address (surf applies
  http.trusted_proxies) on the resolve context and ResolveBackendToken logs it
2026-10-23 16:21:37 +02:00
Jakub Zych
0ec00f7f69 docs(19.7-07): record the member token scope design decision (E-2, P-30) 2026-10-23 16:15:43 +02:00
Jakub Zych
9eedfbbb29 feat(pact): add HasFrontendTokenScopes and the shared ValidTokenScopeName rule (E-2)
- pact.FrontendTokenScope and pact.HasFrontendTokenScopes declare member
  (usr_) token scopes; the admin token catalog never reads them
- pact.ValidTokenScopeName carries cabana's scope-name pattern; cabana's
  g15_ catalog switches to it with unchanged behaviour and messages
2026-10-23 16:15:25 +02:00
Jakub Zych
c14238b94b feat(bouncer): stamp auth_time at sign-in and carry it unchanged through refresh (C-CR-02)
- MintAudience stamps auth_time equal to iat; refreshAudience copies the
  presented token's value and never renews it (absent stays absent)
- bouncer.ClaimAuthTime and bouncer.VerifyAuthTime for plugins, with the
  same signature, audience and expiry checks as VerifyClaims
- TestAuthTimeSmoke traces mint, refresh and read
2026-10-23 16:13:49 +02:00
Jakub Zych
60a86677f2 docs(phase-19.7): update tracking after gap wave 1 2026-10-23 16:11:17 +02:00
Jakub Zych
6ca9e1706d docs(19.7-06): complete lane A gap-closure plan in pier 2026-10-23 16:10:52 +02:00
Jakub Zych
95f177b1e0 docs(cooler): give KeyPrefix and keyPrefix their own doc comments (A-IN-02) 2026-10-23 16:08:27 +02:00
Jakub Zych
211cec11b0 fix(pact): add MCPPrompt.Writes so a write-directing prompt sits under the read/write ceiling
- pact.MCPPrompt.Writes (additive; the zero value keeps today's listing)
- pier's allowsPrompt hides a prompt declared with Writes from an identity
  without write, as it hides a tool that is not read-only (C-IN-01
  framework part, P-28)
2026-10-23 16:08:27 +02:00
Jakub Zych
104db9959f fix(pier): refuse path values the mux never delivers and harden dispatch
- a path field must be required in the reflected schema (boot error), and
  a missing value, an empty, . or .. segment, or a / inside one segment is
  a tool error before dispatch (A-WR-01, A-WR-02)
- a failed guard dispatch logs its cause and answers a fixed tool text;
  only an invalid token and an unknown or deactivated account keep their
  own fixed texts (A-WR-08)
- path and query scalars decode with UseNumber, so integers above 2^53
  keep their digits (A-IN-04)
- the dispatched request carries the outer Host, X-Forwarded-Proto and
  X-Forwarded-Host (A-IN-05)
- an embedded struct on a GET or DELETE tool fails boot (A-IN-07)
- a dispatch whose guard list or principal kind contradicts the tool's
  guard is refused (A-IN-08)
2026-10-23 16:05:32 +02:00
Jakub Zych
240457291f fix(pier): widen returning identities, warm the Redis store, end stateless listen streams, refuse personal tokens without a TokenID
- Identity.fingerprint covers scopes, both subjects, the ceiling and the
  token kind; a stateful lookup or stateless hit whose fingerprint changed
  re-filters the server with the event diff under its own mutex (A-WR-04)
- Mount warms a Redis store in the background with a 1 s to 30 s backoff
  and every request kicks a pending open without waiting, so stateless-only
  instances subscribe to fan-out (A-WR-05)
- a stateless subscriptions/listen POST re-verifies its bearer every
  recheck interval; an LRU-evicted stateless server closes its sessions
  (A-WR-06)
- resolvePersonalToken refuses a subject with TokenID 0, and the
  pact.MCPPersonalTokenResolver contract says one resolver per application,
  false means unauthorized and TokenID keys the binding (A-WR-09, A-IN-03)
2026-10-23 15:59:54 +02:00
Jakub Zych
c1c0c77ddc fix(pier): reserve session slots atomically and build servers outside router locks
- an unexported reserver (Reserve, Release) next to updater: the memory
  store reserves under its mutex, the Redis store in one Lua script
  (prune, SCARD, SET PX plus SADD); serveNew reserves instead of Count
  then Put and releases on a failed connect or initialize (A-WR-03)
- serveNew, lookup's rehydration and the stateless getServer build the
  SDK server with no router-wide lock held and insert or adopt under the
  lock afterwards, so a slow guard or database check no longer stalls
  the instance (A-WR-07)
2026-10-23 15:56:57 +02:00
Jakub Zych
2bf9dca603 fix(pier): reap stateful sessions whose store record expired
- a reaper started at Mount checks every local session against the store
  every min(idle_ttl/2, 1m) and closes each copy whose record is gone,
  logging the expired step (A-CR-01, A-IN-06)
- the GET stream re-check ends the stream when the record is gone (A-IN-01)
- tool calls served without a session on the stateful path log the
  session as ephemeral (A-IN-06)
- TestPierReaperSmoke and the ReapNow, LocalSessions, StopReaper seams
2026-10-23 15:50:04 +02:00
Jakub Zych
d18d8f0dc2 docs(19.7): ban and password reset revoke OIDC grants as well as MCP grants (user decision) 2026-10-23 15:46:44 +02:00
Jakub Zych
d763e92650 docs(19.7): gap-closure plans 06-09 for the review findings and the sm-servers-app escalations 2026-10-23 15:44:15 +02:00
Jakub Zych
2527498d03 docs(19.7): gap-closure plan split and release order 2026-10-23 15:03:52 +02:00
Jakub Zych
cee58c0f65 docs(19.7): gap-closure inputs: review findings and two sm-servers-app escalations 2026-10-23 15:02:44 +02:00
Jakub Zych
fef1cbbbbd docs(19.7): add code review report 2026-10-23 14:54:54 +02:00
Jakub Zych
5563df7e68 docs(phase-19.7): update tracking after wave 5 2026-10-23 14:42:11 +02:00
Jakub Zych
d9d2acae88 docs(19.7-05): plan 05 summary; phase gate green, security review done, plugin test commits local 2026-10-23 14:41:38 +02:00
Jakub Zych
4730e37742 docs(19.7-05): security review and contract, deferred items, folded todos closed
- 19.7-SECURITY-REVIEW.md: T-19.7-01..41 and T-19.7-SC with file, line and
  pinning test; two production fixes (c49983d, 1111828); superuser reach
  accepted as designed with audit and ceiling
- 19.7-SECURITY.md: threats_open 0, accepted risks AR-19.7-01..05
- the frontend permission and account link todos move to todos/done with
  their closing notes
2026-10-23 14:29:56 +02:00
Jakub Zych
0b8e027b81 test(19.7-05): security review pins for the MCP endpoint's outer layers
- TestEndpointGuards: a foreign browser Origin is 403 before the bearer is
  read, a body over the endpoint cap is 413, a long GET stream ends once
  its grant stops verifying (T-19.7-18, T-19.7-19)
- TestDispatch: an argument key the input struct does not declare is
  refused before dispatch (T-19.7-17)
- the gate requires TestEndpointGuards (untagged and tagged) and runs the
  demo's deploy check (T-19.7-37)
2026-10-23 14:26:26 +02:00
Jakub Zych
d621ef1b41 docs(19.7-05): validation map filled, Wave 0 complete, Nyquist compliant 2026-10-23 14:24:13 +02:00
Jakub Zych
a94bdc199d test(19.7-05): gate stages plugins, consumers, docker and docs
- plugins: vet, short tests and the additive-export check of the user
  (GOWORK=off, against 930b158 and v0.1.9), OAuth server (d31f8e7) and blog
  (ffa2c8f) plugins, the blog plugin's MCP tests by name
- consumers: the three applications build and pass at their pins, the demo
  also with the MCP tag; the pin check accepts a plugin submodule ahead of
  its pin only by test-only commits
- docker: the cabana, user plugin, OAuth server and demo Postgres suites by
  name
- docs: decision note and STACK rows, docs checks, no consuming application
  named in sources, docs or the phase's tests
- self-test proves additive_check on a planted repository
2026-10-23 14:24:13 +02:00
Jakub Zych
f14eae96dd test(19.7-05): framework unit tests for every validation row and the gate's admin stage
- pier: TestCatalog, TestDispatch, TestGuardRules, TestSessions (Redis
  across two instances and the memory store), TestFanOut; the store clock
  and stateless-server seams in export_test.go
- surf: TestStreamingRoute (throttle, CORS profile and access-log pattern on
  a stream route) and TestPierMount in both builds; the streaming smoke
  restores the mount hook it replaces
- wristband TestMCPScopes; cabana TestAccountContributions (Postgres part:
  transaction and unchanged My account payloads), TestRecordActionPrompt,
  TestScopeLimitForMethods; TestRecordActionPromptRun pins the empty Value
  of an action without a prompt
- vitest: 403 and failed-load cases for My account contributions, the
  cancelled prompt
- gate: every name required (tagged runs included), account.go unchanged
  since 51d088a, admin stage live
2026-10-23 14:04:16 +02:00
Jakub Zych
1111828e8a fix(pier): an ended session is never written back by a request still in flight
- persisting a session's protocol state after a request now rewrites an
  existing record only (Redis SET XX, the memory store likewise) and closes
  the local copy when the record is gone
- before, a request that finished after DELETE, a revoked or deleted subject
  event or the idle expiry put the record back, and the next request
  rehydrated the ended session
- found by plan 19.7-05's TestFanOut (revocation and deletion cases, about
  one run in a hundred)
2026-10-23 13:55:04 +02:00
Jakub Zych
c29d2289d0 fix(pier): a tools/call without arguments or with null arguments is an empty object
- MCP's tools/call arguments are optional; pier validated a JSON null
  against the input schema and refused every call of a tool without
  required input that an agent sent without arguments
- found by plan 19.7-05's TestDispatch
2026-10-23 13:33:24 +02:00
Jakub Zych
3bbbe6c11e test(19.7-05): phase gate with the go and marker stages, pier test helpers, TestToolsList and TestDispatchMarker
- scripts/check-phase19.7.sh: fail-closed multi-repo gate (self-test, go,
  marker; plugins, consumers, docker, admin and docs are stubs until the
  later tasks fill them)
- modules/pier/helpers_test.go: the plan 02 fixtures moved out of the smokes
  plus fakeGuard, fakeVerifier, fakeLinkResolver, fakePersonalResolver,
  routePlugin, newApp, twoInstances, sdkClient and fireSubjectChanged
- TestToolsList (pier), TestDispatchMarker (bouncer, cabana with a Postgres
  part through the screens harness, which now keeps its app)
2026-10-23 13:31:41 +02:00
Jakub Zych
c49983d3f8 fix(cabana): the backend middleware refuses a dispatch marker carrying a frontend principal
- cabana wraps the bouncer backend guard middleware: a marker that lists the
  backend guard with Backend false answers 401 before the guard honours it,
  as ResolveBackend already does, so a frontend user id is never read as an
  administrator's by the admin API or a backend-guarded plugin route
- found by plan 19.7-05's TestDispatchMarker (admin API in-process case)
2026-10-23 13:27:25 +02:00
Jakub Zych
905111ba72 docs(phase-19.7): update tracking after wave 4 2026-10-23 13:18:15 +02:00
Jakub Zych
81266de77d docs(19.7-04): plan 04 summary; oauthserver v0.1.2 and Journal v0.2.3 released, pinned in the demo
- SUMMARY with every deviation from the checkpoint report
- deferred items: sm-demo-app push and deploy wait for the user, release
  builds on summercms v0.4.4 lack the cabana subject-event fix, Redis for a
  second instance, the real-client check, the retracted mimetype
2026-10-23 13:17:36 +02:00
Jakub Zych
9550fe0a9f docs(19.7-04): deferred items from the oauthserver, Journal and demo MCP wiring 2026-10-23 12:56:08 +02:00
Jakub Zych
29ba9a28cb docs: log cabana subject-event fix 2026-10-23 12:44:15 +02:00
Jakub Zych
7c43820afe docs(19.7): cabana subject-event bug resolved 2026-10-23 12:44:09 +02:00
Jakub Zych
d96c726d6c fix(cabana): backend subject events reach pier as *pact.MCPSubjectChanged, fired after the transaction commits 2026-10-23 12:44:09 +02:00
Jakub Zych
5c35f83b9d docs(phase-19.7): update tracking after wave 3 2026-10-23 12:31:00 +02:00
Jakub Zych
607658599f docs(19.7-03): sm-user-plugin v0.1.10 released and pinned in five apps; cabana subject-event bug deferred
Plan 03 summary: verified account link, Administrators-screen link actions, plugin frontend permissions, user MCP guard and user_me in sm-user-plugin v0.1.10 (requires SummerCMS v0.4.4). deferred-items: cabana fires pact.MCPSubjectChanged as a value inside the transaction while pier listens for a pointer; fix before v0.5.0.
2026-10-23 12:30:15 +02:00
Jakub Zych
d039350729 docs: record the v0.4.4 and sm-user-plugin v0.1.9 releases 2026-10-23 00:31:56 +02:00
Jakub Zych
e2759d668f docs: user-plugin escalations released in sm-user-plugin v0.1.9, reply ready to send v0.4.4 2026-10-23 00:25:24 +02:00
Jakub Zych
eadd58414d docs(19.7-02): close plan without a release 2026-10-23 00:23:08 +02:00
Jakub Zych
a26ee2b72d docs(quick-261022-x7a): user-plugin golem15.user.password.public_routes switch, login/forgot/reset 404 when false 2026-10-23 00:15:49 +02:00
Jakub Zych
e5dd4579a8 docs: fill item 8 in the external-escalation reply 2026-10-23 00:10:27 +02:00
Jakub Zych
894a3d572f docs(19.7): next v0.4.x release after the quick tasks, v0.5.0 at phase completion 2026-10-23 00:08:10 +02:00
Jakub Zych
d1a15a6f5f docs(19.7): tag v0.5.0 only when phase 19.7 is complete 2026-10-23 00:05:39 +02:00
Jakub Zych
a9e3f2434d docs: tune item 8 password-routes quick after item 7 2026-10-22 23:53:43 +02:00
Jakub Zych
cd90be9de3 docs(quick-261022-wah): user-plugin opt-in token_cookie session cookie and cookie-carried /refresh rotation 2026-10-22 23:51:57 +02:00
Jakub Zych
6a1974c0d2 docs: fill item 7 in the external-escalation reply 2026-10-22 23:45:20 +02:00
Jakub Zych
ec69f547b8 docs: tune item 7 cookie quick after 9-10 2026-10-22 23:14:09 +02:00
Jakub Zych
e9ebf93d36 docs(quick-261022-vfz): user-plugin /login throttle via surf.ClientIP and whole-second tokens_valid_after writers 2026-10-22 23:08:04 +02:00
Jakub Zych
c309a1abe9 docs: tune items 9-10 quick after G4 2026-10-22 22:37:41 +02:00
Jakub Zych
575a110378 docs: fill G4 in the external-escalation reply 2026-10-22 22:36:19 +02:00