Skip to content

v0.17.0

Choose a tag to compare

@github-actions github-actions released this 25 Sep 12:58
57616e9

Hub 0.17.0 moves to Authup 1.0.0-beta.68 and fixes Harbor provisioning, which never ran. It covers everything since v0.16.1.

📣 Some News

This release is mostly about authorization. Hub used to cut every introspected grant down to a bare permission name, which dropped the grant's policies and its realm reach. From now on the grant reaches the evaluator whole. Authup and Hub have to be upgraded together, and a restricted service client may need one extra grant. The heads-up table below lists what to do.

👀 Highlights

🔐 Authup beta.68 and the authorization catalog

Hub now requires Authup 1.0.0-beta.68. Every authenticated HTTP request and every socket connection fetches Authup's authorization catalog (GET /authorization) once, using the service's own CLIENT_ID / CLIENT_SECRET. It then builds a local evaluator from that catalog plus the caller's complete introspection grants and identity. All later permission checks in that request or connection run locally against the evaluator.

Before this, grants were reduced to permission names. A grant's policy tree and its realm scope were thrown away before any check ran. Now they survive to the evaluator.

The same helper the middlewares use is exported from @privateaim/server-kit:

import { createAuthupPermissionEvaluator } from '@privateaim/server-kit';

// one catalog read, then every check runs locally
const evaluator = await createAuthupPermissionEvaluator(authupClient, input);

Warning

The service client needs permission_read with realmScope: "ownOrNull" (single realm) or "any" (several realms). The default "own" scope cannot read global policy definitions. The built-in system client already has this access. A custom, restricted client without it fails every authenticated request: catalog errors fail closed, with no fallback to permission names.

Note

Endpoints that only ran a permission pre-check still only run a pre-check. This release does not add row-level policy checks or collection filtering. Catalogs are not cached across requests. Token-introspection caching and socket session lifetimes are unchanged, so a grant change shows up when those refresh.

📖 Authup upgrade to beta.68

🧭 Navigation follows permission changes

The frontend now gets UI permission verdicts from one POST /authorization/check batch. It refreshes that batch when the policy expiry returned by Authup runs out. The header and sidebar in client-ui re-resolve their items whenever store.permissionRevision changes, so a menu entry appears or disappears without a reload. Browser users do not need permission_read to render menus.

If you build your own navigation on @privateaim/client-vue with an async resolver, add the same watch source:

 const watchSources = [
     () => store.status,
     () => store.userId,
     () => store.realmManagement,
+    () => store.permissionRevision,
 ];

📖 Authorization catalog

🧵 Serialized strings keep their type

Authup beta.68 quotes strings when serializing them. Values like "123", "true" or "" now come back as strings instead of being read as a number, a boolean or nothing. Hub's serializedTextTransformer (@privateaim/server-db-kit) reads both the new quoted form and the old unquoted form, so messenger payloads already stored stay readable.

Note

No Hub data migration is needed. Authup's own beta.67 migration does run, and it pins database timestamps to UTC. If your Authup database stored local time, read the Authup beta.67 upgrade notes first.

🚢 Harbor provisioning actually runs

Linking, relinking and unlinking a node's registry project did nothing, on every boot. RegistryManagerAdapter resolved RegistryComponentCaller once, while the database module was being set up. But the components module that registers the caller always runs after the database module, so the adapter ended up with no caller and stayed that way.

What this broke: no Harbor project, robot account or webhook was ever created by Hub. That covers auto-assignment on node creation, the Switch / Connect / Disconnect actions on a node's Registry tab, and the registry project's own "Connect" repair action. The node still looked connected, because registryId / registryProjectId were written correctly. Only the remote side was missing.

The adapter now resolves the caller on each call, so module order no longer matters.

Tip

After upgrading, re-run Connect on nodes that were connected while running an affected version. That creates the Harbor project, robot account and webhook they are missing.

📖 #1893

⚠️ Heads-Up Before Upgrading

Change What to do
Authup 1.0.0-beta.68 required Upgrade the Authup server together with every Hub service
Services read GET /authorization with their own client Give restricted service clients permission_read at realmScope: "ownOrNull" or "any". The built-in system client needs nothing
Authup beta.67 pins timestamps to UTC Follow Authup's beta.67 notes if its database used local time
@privateaim/client-vue peers moved Use @authup/* ^1.0.0-beta.68, @rapiq/core ^2.4.0, vue ^3.5.43, vue-router ^5.3.1, @vuecs/core ^3.6.0
Custom async navigation Add store.permissionRevision to its watch sources
Harbor links made on an affected version Re-run Connect on those nodes

⬆️ Upgrading

docker pull ghcr.io/privateaim/hub:0.17.0
npm install @privateaim/client-vue@^0.17.0 @privateaim/core-http-kit@^0.17.0

📖 Deployment configuration

👉 Changelog

v0.16.1...v0.17.0

⚠ BREAKING CHANGES

  • auth: Hub requires Authup beta.68. Restricted service clients need permission_read with ownOrNull or wider realm reach; the built-in system client already has this access.

Features

  • auth: upgrade Authup to beta.68 and use its authorization catalog (#1903) (f7e0baa)

Bug Fixes

  • server-core: resolve RegistryComponentCaller lazily so Harbor provisioning actually runs (#1894) (62c4b2b), closes #1893