Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0e747-8f27-7242-8df8-8bc44f88c929
16 KiB
Hub Core and extension access through NetKingdom
Status: reviewed source blueprint; owner/live acceptance pending, 2026-09-28. Owner: hub-core.
Execution record: HUB-WP-0012.
Requested outcome: the person signing in as platform-root can access and
administer the whole platform, including Hub Core, its extensions, and Railiance.
Other human users are denied initially. Public exposure follows proven access
enforcement. Fine-grained delegation is a later phase of the same workplan.
The access profile candidate records the subsequent source implementation and remaining integration gates. The table below is the original pre-implementation baseline, not a claim that the new enforcement is deployed.
Findings and evidence boundary
This is a source/configuration review plus read-only runtime observation, not an authenticated platform-root acceptance test. No account, token, role, policy, public listener, or production workload was changed.
| Boundary | Observed state on 2026-09-28 | Consequence |
|---|---|---|
| Hub Core | runtime/app.py mounts ports.py without a global authorization dependency; native registration, messaging, events and generic projections lack a verified subject/tenant context |
Enforce access in the service and SDK, not only at Ingress |
| Compatibility API | runtime/compat.py::_protected accepts a shared configured bearer or an imported consumer key; no resource/tenant decision follows |
Replace broad bearer authority with authenticated principal plus action authorization |
| MCP | Separate runtime/transport and reusable host wrapper | Inventory every tool and carry caller identity to the same protected API; no server-wide root token |
| Inbox pilot | Snapshot GET reader uses the shared token and literal state-hub recipient |
Keep private; caller migration remains HUB-WP-0011, not a completed retirement slice |
| Extension conformance | HUB-WP-0009 finished C2/C7/C9/C10; its explicit tenant-isolation gap has no implementation | This workplan owns the new security profile; 0.1 conformance is insufficient for exposure |
| Identity | Live issuer discovery at https://kc.coulomb.social advertises S256, authorization code and client credentials; KeyCape, Authelia, LLDAP and identity-provisioner Deployments Ready |
Reuse the issuer; no second identity database or new IdP |
| User and tenant management | User Engine and Tenant Engine Deployments Ready; USER-WP-0030 and NK-WP-0038 finished | Reuse account lifecycle and tenant authority; readiness does not prove this root account's effective grants |
| Policy | Six service-specific flex-auth Deployments Ready; none for Hub Core | Register a protected system and owner-managed policy deployment; don't borrow another consumer's PDP/credentials |
| Hosting | Core Hub legacy/candidate/publisher Ready; revision 28 has Ingress off | Keep private until the new admission gate; the earlier public grant alone does not satisfy this request |
| Current external blockers | Public host presents Traefik default certificate; publisher accepts 113/123 with nine private-source errors and an identity-canon registry mismatch | Existing RAPPCOREHUB-WP-0002/0003 retain these operational obligations |
Source findings use the current checkout. Live hub image remains the September 5 pin, so later source conformance changes are not claimed deployed. The root account's immutable subject, effective memberships, MFA and revocation behavior still require an attended, non-secret acceptance receipt.
Authority and request path
flowchart TD
Human[Human: platform-root] --> Login[KeyCape OIDC login]
Login --> Client[Hub browser session or CLI]
Users[User Engine: account and membership lifecycle] --> Facts[Verified account and tenant facts]
Tenants[Tenant Engine: tenant lifecycle and capability roles] --> Facts
Client --> Hub[Hub Core API: authenticate and enforce]
Workload[Named service or agent identity] --> Hub
Facts --> Policy[flex-auth: action and resource decision]
Hub --> Policy
Hub --> Extension[Extension API: authenticate and enforce]
Extension --> Policy
Extension --> Owner[Railiance or domain owner: execute and enforce]
Owner --> Audit[Durable audit evidence]
Hub --> Audit
KeyCape owns authentication and signed IAM claims. User Engine owns account,
application profile and membership lifecycle. Tenant Engine owns tenant state
and capability roles. NetKingdom owns the IAM profile and identity integration.
flex-auth owns decisions; the announced access-engine rename changes a repo
coordinate, not current runtime names or audiences (NK-WP-0039).
Hub Core and every extension enforce decisions locally. Domain services retain their data, commands and approvals. Railiance retains infrastructure execution; ops-warden retains SSH certificate issuance; approval-engine retains durable approval lifecycle; OpenBao/platform owners retain credential custody. Hub Core does not become a privileged Kubernetes or OpenBao proxy merely by hosting UI.
M1: full platform-root access
Bind the existing platform-root account by verified (issuer, subject), resolved
through its owning identity/account records. A username or email is only a
display/lookup hint, never the privilege check. Do not fabricate a subject UUID,
auto-promote the first login, or grant every platform-operator root access.
User Engine currently uses platform-operator for some administrative gates;
T02 must map the specific root account's entitlement into those existing policy
vocabularies rather than assume a universal platform-root role already exists.
M1 grants that principal all registered platform actions and resources through
each service's normal enforcement path, including Hub Core registry, messaging,
events, projections, work/repository operations via owners, extension surfaces,
tenant administration, and Railiance administration. Where full administration
requires crossing tenant boundaries, record an explicit platform-root grant
and audit both actor tenant and target tenant. Root remains tenant:platform;
it does not impersonate a tenant member. Tenant admins and ordinary users gain
no platform access in M1. Workloads retain only their individually registered
service/agent permissions and cannot inherit the human grant.
Use a versioned, owner-reviewed action/resource catalog and entitlement, not a hardcoded middleware bypass. New actions require catalog/policy review before they become routable. Fine-grained human roles are deferred, but signature validation, deny-by-default, tenant attribution and audit are M1 requirements. Full access does not waive existing confirmations, approval obligations, single-writer controls, secret non-disclosure, or emergency custody rules.
The estate access matrix must enumerate every active platform service and management surface from owner/Fabric inventories. Seed it with Hub Core, ops-hub, repo-manager, activity-core, User/Tenant Engine, identity administration, policy/approval/audit surfaces, Forgejo, OpenBao/secrets operations, and Railiance Kubernetes, deployment/GitOps, SSH and observability. Each row names owner, resource/realm, audience, enforcement point, grant, safe test, and receipt. Existing native/SSH/attended paths may satisfy a row; a generic hub token may not. M1 is not complete while any inventoried platform surface is inaccessible or untested. Non-hub services need integration, not reclassification as hubs.
Authentication and session contract
Use accepted IAM Profile v0.3. The browser uses Authorization Code + PKCE S256 through a confidential session backend with exact registered redirects, state/nonce, Secure HttpOnly cookies, CSRF protection and logout. Store tokens server-side, not browser local storage. CLI/MCP clients use an issuer-supported flow and their own audience-bound credentials; do not assume device flow or token exchange exists without proof. The OAuth design follows RFC 9700.
The API validates access-token type, issuer, audience, allowed algorithm, signature, key rotation, expiry/not-before and required IAM claims. ID tokens are not API credentials. Missing/invalid authentication returns 401; verified but disallowed access returns 403; unavailable authorization returns a bounded 503 without executing work. Resolve trusted resource/tenant facts on the server; ignore user-supplied subject, role, tenant headers and purported verified flags.
Platform-root requires AAL2 or stronger per IAM v0.3 and NK-ADR-0016; an ordinary SSO session does not establish that. Reuse the accepted enrollment/recovery journeys and attest the privileged login. NK-WP-0042's per-request step-up and IAM v0.4 are proposed, not available guarantees. M1 can use the existing per-client privileged MFA path only after its usability/return journey is accepted; otherwise remain private and record that blocker.
T02 fixes measurable token/session lifetimes, assurance freshness and maximum
grant-revocation delay. Proposed upper bound: five minutes for ordinary root
access; privileged mutations recheck current root entitlement and tenant state
at execution and fail closed when unavailable. Logout invalidates the local
session immediately; expired or revoked authority cannot survive refresh.
Use authoritative owner APIs for high-stakes tenant capability facts;
tenant_roles in a token is only a cache. Test user suspension, grant removal,
tenant suspension and issuer/policy outages, not just successful sign-in.
Authorization, forwarding and extension contract
Every request carries server-established actor, calling workload, target tenant, action, resource, assurance and correlation identity. The service authenticates to flex-auth using an admitted workload identity separately from the end user's identity. Caller TokenReview alone must not authorize arbitrary claims asserted by that caller. Adopt the current fact-provenance and binding contracts (FLEX-WP-0025, FLEX-WP-0017).
Verify the decision's request binding, action/resource/tenant, validity, policy version, obligations and authenticated origin. Require a signed decision and trusted rotating verification keys per FLEX-WP-0024, or an explicitly reviewed equivalent authenticated channel. An unsigned development decision is not sufficient for public M1. Signing code being finished does not prove a production signing-key custody lane exists; owner delivery is a T03 gate. Audit allow/deny/error with actor, caller, tenant, action/resource, policy and decision IDs, correlation and outcome; never tokens or message bodies. Required audit failure prevents privileged mutation; bounded durable buffering must be specified rather than silently dropping evidence.
Expose one reusable enforcement/context seam for embedded routers, native
/ports, /api/v2, aliases, docs/catalogs, projection APIs, browser and MCP.
Only minimal liveness and the exact login/callback mechanics may be unauthenticated;
detailed readiness is internal. Test direct Service requests as well as Ingress.
Legacy keys get explicit private, bounded migration lanes with named owners;
they must not become a public bypass or be distributed to extensions.
An extension manifest declares protected-system identity, token audience,
action/resource namespaces, tenant behavior and required security-contract
version. Extensions validate their own audience and enforce their own policy;
Hub Core cannot forward a bearer to an unrelated audience. Use only a proven
issuer delegation/exchange mechanism, or a reviewed authenticated workload call
with integrity-bound end-user delegation. If neither exists, use a separate
client login and leave delegation unsupported. Never relay root's bearer as a
generic backend credential. Service-initiated events bind producer/address to
the authenticated workload; payload sender is not authority.
Version the security profile and extend conformance beyond HUB-WP-0009. Cover list/filter/detail, exports, caches, pagination, broadcasts, aliases, streaming/MCP and event replay; no cross-tenant existence/count leak. Classify legacy unlabelled records explicitly as platform-owned or quarantine them; never infer their tenant from the current viewer. Platform-root may administer them through its explicit platform grant. Non-root multi-tenant admission waits for Phase 2 data migration and isolation tests.
Retirement integration and sequencing
| Existing owner record | Relationship to this work |
|---|---|
| HUB-WP-0004/0005, CORE-WP-0010 | Runtime selection/absorption already decided; implement here, retain Core Hub rollback privately; no new feature lane in Core Hub |
| HUB-WP-0009 | Existing contract checks stay finished; this work owns the missing identity/tenant conformance profile |
| HUB-WP-0011 | Reuse the new caller/context seam for T02; inbox freshness, retention, recipient/alias semantics and reader switch stay there |
| STATE-WP-0079 | Authentication does not close its 425-item disposition, single-writer, parity, metering or retirement gates; apply the security gate per slice |
| RMGR-WP-0001/0002/0003 | Git/file authority stays in Repo Manager; Hub Core views and invokes governed owner APIs |
| OPS-WP-0003; ACTIVITY-WP-0029 | Existing extension and event/schedule alignment finished; add security conformance/caller migration without reopening completed tasks |
| FIN-WP-0003; RAIL-FAB-WP-0028 | Fabric authority stays specialized; hosted Fabric is blocked independently; integrate the available owner surface and report missing runtime evidence |
| RAPPCOREHUB-WP-0002/0003/0004 | Packaging/exposure, publisher credential gate and completed private inbox pilot retain their owners |
| NK-WP-0038/0039/0042; USER-WP-0030; TEN-WP-0012 | Reuse delivered identity/admin behavior; respect pending coordinate, step-up and tenant conformance work rather than claim them complete |
Implement shared contracts and platform-root access privately first. Exercise one extension (ops-hub), actual workload callers and Railiance owner paths, then complete the platform access matrix. Gate each State Hub reader/writer move on the same identity checks plus that slice's existing data/freshness gates. Do not add permanent authentication/tenant authority to retiring State Hub.
Public enablement is a separate final gate under RAPPCOREHUB-WP-0002: authenticated root success, ordinary-user/anonymous denial, direct-path denial, MFA, revocation, policy failure, audit, all published route/tool coverage, current image pins, TLS issuance and consumer tests, then explicit exposure approval. Fix release configuration so routine upgrades preserve the approved exposure mode while new installations default private. Do not expose the legacy rollback service. Rollback retracts public access before restoring any image lacking enforcement; it never restores an anonymously reachable older runtime. No full historical Helm rollback that silently revives the old public configuration.
Later phase retained in the same plan
After M1, define tenant-admin and ordinary-user grants, delegated agents, per-extension/action permissions, recipient ACLs and tenant-scoped storage, queries, caches and retention. Preserve the root entitlement as an explicit policy grant. Phase 2 is open work, not a prerequisite for proving the coarse root-only model, and must not be silently dropped when M1 closes.
Source map
hub-core/hub_core/runtime/{app,ports,compat,config,inbox_projection}.py,hub_core/mcp/server.py,docs/runtime.md,docs/conformance.md.- NetKingdom
docs/platform-identity-security-architecture.md, accepted IAM v0.3,docs/adr/ADR-0016-mfa-user-preference-and-workload-step-up.md. - User Engine
wiki/ArchitectureBlueprint.md,docs/development.md; flex-authdocs/iam-profile-consumption.md, decision binding/signature and inbound caller-auth contracts. The older consumption doc's v0.2 reference does not supersede accepted additive v0.3. - Retirement project
architecture/hub-extension-architecture_v0.1.md,architecture/child-workplan-map_v0.1.md, and owner workplans in the table. Historical map statuses are not treated as current delivery evidence. - Runtime checks: deployment readiness listing, issuer discovery, and
rapp-core-hub/docs/evidence/loose-end-review-20260928.md.