Implementation notes
Platform X and Simplexable Services
Technical source for integrating @simplexable/services-platform-client@0.1.0. A Platform X delegates centralized user and group authority to Services and retains ownership of application and domain behavior.
§1 Purpose — ownership boundaries
“Owns” means that party is the only authority that may establish, mutate, or invalidate the fact. The other party may consume a projection of the fact but MUST NOT invent, rewrite, or co-author it. There is no supported hybrid or co-authoritative identity model.
Services owns
- Centralized identity (users and groups as Services-defined facts)
- Authoritative group/user state and the group SSoT revision
- Authentication and session establishment
- Actor-token issuance and validation
- Platform-X deployment registration and group binding
- Machine credentials (digest-only persistence)
- Determination of whether a committed change is revision-worthy
- Post-commit refresh notification to the registered Platform X endpoint
- Registration/connection truth for the group’s dataset (host, database, port, role, password)
Platform X owns
- Application and domain behavior
- Local authorization policy that decides whether a human may ask Services to mutate Services-owned identity
- Local SSoT projection / repository and how the application uses it
- Application-specific configuration
- Its refresh HTTP endpoint
- Reactions after a refreshed identity snapshot is adopted (cache invalidation, websocket fan-out, UI refresh, and so on)
§2 Architectural model
2.1 Runtime relationship
After login/handoff, Platform X clients ordinarily talk only to the Platform X backend. The Platform X backend talks to Services when Services authority is required. Browsers MUST NOT become Services API clients.
Browser
|
Platform X frontend
|
Platform X backend
|-- Services auth/handoff: /users/login-password, /users/login-key,
| /users/validate-handoff (not the SSoT contract)
|
+-- Services /external/v1 (machine SSoT, connection, actor mutations) 2.5 Notification-driven refresh
Services notifies only after commit, and only when the change is revision-worthy. Notification failure MUST NOT roll back committed Services state.
Services authoritative change
|
COMMIT
|
post-commit refresh notification
|
Platform X refresh endpoint
|
SSoT repository reread
|
local adoption
|
Platform X consumers How Platform X works
These are separate concerns (per the web extraction guide). Do not collapse them into a single “Services client” story.
Human login / handoff (§2.2, §11 step 4)
Current auth uses /users/login-password,
/users/login-key, and
/users/validate-handoff until an external-v1 auth contract
exists. Not a SSoT fallback. The Platform X backend receives
actorToken and MUST keep it server-side only.
Machine authentication (§3.A, §6)
Backend-only px1 credential for /external/v1:
Authorization: Bearer px1.<credentialId>.<secret> Human actor authority (§3.B, §11 step 3)
Actor JWT is backend-only; required for actor-authorized mutations and
GET /session; fail closed if missing. Persistence is host
policy.
X-Services-Actor: Bearer <actor JWT> Authoritative SSoT (§2.3, §7)
Services owns users/groups and the revision. Platform X adopts a
projection via conditional GET (ETag /
If-None-Match). The package repository adopts a higher
revision, refuses regression, and fail-closes on empty cache plus
transport/auth failure.
Refresh notification (§2.5, §9)
After commit, Services POSTs to the registered refresh URL. Body is
exactly { "target": "<opaque target>" } (see §9). Platform X
validates Bearer auth, matches opaque target, rereads SSoT.
Secure installation (§12–§16)
Provisioner stdout → installer stdin; protected env 0600; no
secret argv; --check / --install /
--verify. Pin
@simplexable/services-platform-client@0.1.0 from the npm
registry (not file:).
§3 Trust and credential model
Three credentials. They are not interchangeable.
| Credential | Header / use | Direction |
|---|---|---|
| Platform machine credential | Authorization: Bearer px1.… | Platform X → Services /external/v1 |
| Services actor token | X-Services-Actor: Bearer … | Platform X → Services (mutations, GET /session) |
| Refresh notification secret | Authorization: Bearer … on refresh POST | Services → Platform X |
Refresh-notification secrets MUST NOT authenticate
/external/v1. Target HMAC is addressing, not
authentication. A leaked machine credential must not forge refresh
doorbells; a leaked refresh secret must not call
/external/v1.
§7 SSoT contract
Canonical DTOs
On-the-wire shapes (Platform X MAY remap field names locally):
ServicesGroup { id, name, active }
ServicesUser { id, groupId, email, name, level, active }
ServicesActor { userId, groupId, level, active, sessionId,
userAuthorityVersion, groupAuthorityVersion } Revision and ETag
- Scope: one
groupId. - Existing/new groups initialize at revision
1. -
ETag:
"group-ssot:{groupId}:{revision}"(literal form:group-ssot:{groupId}:{revision}). - Conditional GET:
If-None-Matchequality →304. -
“CURRENT” is established only by successful SSoT reread (or
304against an existing snapshot), not by notification alone.
Notification is not data
Notification means only: reread the Services users/groups SSoT for this target. It MUST NOT carry users, group name, revision, or mutation type.
§8 Mutation contract
machine authority
+ human actor authority
+ Idempotency-Key
+ If-Match revision (visible-state mutations) Services validates machine and actor, applies If-Match where required, mutates authoritative state, increments group SSoT revision once when the change is revision-worthy, persists idempotency in the same transaction, COMMITs, then notifies after commit if revision-worthy.
Revision-worthy: group name change; user create; visible user profile change (name, email, level); user deactivate / reactivate.
Not revision-worthy: password-only change; no-op updates; registration / connection / api_token / api_url / server_timezone changes.
Package: identity.updateGroup, createUser,
updateUser, deactivateUser,
reactivateUser send If-Match from
expectedRevision.
identity.setUserPassword sends
expectedUserAuthorityVersion (no If-Match).
§9 Refresh notification contract
POST <refresh-url>
Authorization: Bearer <notificationAuthSecret>
Content-Type: application/json
{ "target": "<opaque target>" } Target derivation:
target = HMAC-SHA256(key = notificationTargetKey,
data = lowercase(trim(groupId)))
as base64url
Receiver (createServicesRefreshHandler): auth mismatch →
401; invalid body → 400; zero local group
matches → 200 generic success; more than one match →
500 fail-closed; exactly one match → invoke
refreshGroup(groupId), then 200. Platform X
MUST reread SSoT after a matched notification.
§10 Package integration
Install exactly
@simplexable/services-platform-client@0.1.0
from the npm registry. Backend only. Node engines:
^24.18.0 || >=26.0.0. The package sets
"browser": false.
| Export | Responsibility |
|---|---|
createServicesClient |
HTTPS client for /external/v1 (machine auth, optional
actor, idempotency, ETag helpers on mutations)
|
createGroupSsoTRepository |
In-memory per-group snapshot, adoption, regression refusal,
ensureFresh / verifyCurrent |
createServicesRefreshHandler | Auth + target match + invoke host refresh |
deriveRefreshTarget / matchRefreshTarget | HMAC addressing |
groupSsotEtag / groupSsotIfNoneMatch | ETag helpers |
ServicesClientError / isServicesClientError | Structured errors |
Typical construction:
createServicesClient({ baseUrl, machineCredential })
createGroupSsoTRepository({ client, onAdopted? })
createServicesRefreshHandler({ notificationAuthSecret, notificationTargetKey, knownGroupIds, refreshGroup }) Platform X still MUST own: protected storage of machine credential, refresh secret, and target key; refresh HTTP route; locally known group ids for target matching; local projection beyond in-memory snapshot if the process must survive restart; actor authority for mutations; local authorization before mutations; browser payload sanitization; TLS with certificate verification; post-adoption application effects.
§11 Platform X implementation checklist
Engineering steps for a new Platform X. Acceptance condition is “done” before moving on.
- Establish the Platform X backend — process isolated from the browser bundle; HTTPS in production; backend starts without embedding Services credentials in frontend assets.
- Install the exact approved package version —
dependencies["@simplexable/services-platform-client"] === "0.1.0"from registry, notfile:; preflight package inspection passes. - Keep actor authority on the Platform X backend —
actor JWTs never enter the browser; fail closed when a valid actor is
unavailable for actor-authorized operations; never return
actorTokenin bootstrap/session JSON to the browser. - Integrate Services login / handoff — complete
Services login, then Platform X backend calls
POST /users/validate-handoff(current Services auth path, not/external/v1). - Instantiate the Services client — all
/external/v1identity, SSoT, mutation, and connection calls through the package; login/handoff remains on Services auth routes in §2.2. - Instantiate a per-group SSoT repository —
createGroupSsoTRepository; callensureFresh/verifyCurrent; refuse lower revision. - Implement the local projection / access boundary —
map
ServicesGroup/ServicesUserinto the platform roster/session model; fail closed when no snapshot exists. - Implement the authenticated refresh endpoint — HTTPS
POST route;
createServicesRefreshHandlerwith notification secret, target key, known group ids, and refresh function that rereads SSoT. - Integrate actor-backed mutations where required — machine + actor + idempotency + If-Match via package methods; local authorization first.
- Keep secrets out of frontend / bootstrap — allowlist bootstrap fields; never send machine credential, actor JWT, refresh secrets, target key, or DB password.
- Configure production TLS — valid certificates; remote TLS verification not disabled.
- Prepare deployment registration inputs — operator can run preflight without secrets on argv.
- Install credentials securely —
migrate-platform-x.sh --install(or provisioner stdout → installer stdin); env0600. - Verify —
--verify/verify-install.mjs; package0.1.0, SSoT loaded, connection fields present without printing password. - Perform controlled acceptance — prove the human path once per new platform type (§16); reversible visible mutation recommended for brand-new platform type, not every later deploy.
§12–§16 Installation and verification
- Preflight (
--check) — non-mutating; validates inputs, package version, permissions. - Install (
--install) — mutating; creates deployment records, machine credential, notification secret, target key; writes protected env. - Verify (
--verify) — mandatory on every install; machine path against live deployment.
Automated verification is mandatory on every install. Behavioral acceptance (login, roster, optional visible mutation) is mandatory for a new platform type, not required to re-prove on routine deploys.
§19 Security invariants
- No machine credential in the browser.
- No actor JWT in the browser.
- No DB password in the browser or in logs.
- No secret-bearing argv.
- Services persists only the machine-secret digest.
- Target HMAC is addressing, not authentication.
- Machine auth, actor auth, and refresh auth are three distinct secrets.
- Production transport is HTTPS; TLS verification not disabled for remote hosts.
- Credential authenticates only the bound deployment/group.
- Stale or legacy actor tokens are rejected.
- SSoT revision regression is rejected.
- Mutation authority remains Services-owned; Platform X sends intent only.
- Refresh body is exactly
{ target }; no identity payload. - Protected env is
0600. - Exact package version
0.1.0until deliberately adopted.
§20 What Platform X does NOT need to implement
- Services password policy or user/email normalization
- SSoT revision policy or “is this change revision-worthy?”
- Actor-token validation semantics (signature, audience, authority versions)
- Target HMAC as if it were a capability
- Duplicate mutation/idempotency stores for Services-owned operations
- A browser-to-Services identity client
-
Legacy
/users/lookup-group,/users/group-ssot-freshness, or/users/group-ssot-projectionas the identity path -
API_ACCESS_TOKEN/user_groups.api_tokenas external-v1 machine auth - Co-authoritative or hybrid user/group ownership
Public extraction from the canonical Platform X implementation
specification (Services reference release
v2026.09.24.03). Omitted: deployment identifiers,
operator hostnames, reference-consumer acceptance narratives,
historical compatibility paths, and internal script paths. Package:
@simplexable/services-platform-client.