Files
qbit-authentik/docs/SYNCHRONIZATION.md
james.maesandGPT-6 2e356b8117
QRun-IO/ci-policy: ci / fork-guard (pull_request) Skipped
QRun-IO/ci-policy: native / fork-deny (pull_request) Skipped
QRun-IO/ci-policy: native / dotnet-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / Scoped workflow [workflow f1d46718955078331817c6206b822a94bc7d769f] (pull_request) Successful in 9s
QRun-IO/ci-policy: ci / head-profile (pull_request) Skipped
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 9s
QRun-IO/ci-policy: ci / repository-policy (pull_request) Skipped
QRun-IO/ci-policy: ci / application-template-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / gradle-1 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-core-2-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (pull_request) Skipped
QRun-IO/ci-policy: ci / node-8 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-9 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-10 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-13 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-14 (pull_request) Skipped
QRun-IO/ci-policy: ci / android-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-business (pull_request) Skipped
QRun-IO/ci-policy: ci / original-mcp (pull_request) Skipped
QRun-IO/ci-policy: ci / original-voyage (pull_request) Skipped
QRun-IO/ci-policy: ci / original-cli (pull_request) Skipped
QRun-IO/ci-policy: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: ci / shared-pipeline (pull_request) Skipped
Shared Java Maven CI with Docker / secrets (push) Successful in 38s
QRun-IO/ci-policy: Shared Java Maven CI with Docker / secrets (pull_request) Successful in 38s
qbit release candidate / cut-rc (pull_request) Failing after 18s
Release candidate / release-rc (pull_request) Failing after 18s
qbit release candidate / tag-and-release (pull_request) Skipped
QRun-IO/ci-policy: Shared Java Maven CI with Docker / verify (pull_request) Failing after 15m39s
QRun-IO/ci-policy: Shared Java Maven CI with Docker / gate (pull_request) Failing after 24s
QRun-IO/ci-policy: ci / java-docker-3 (pull_request) Failing after 1h14m34s
QRun-IO/ci-policy: ci / ci-result (pull_request) Failing after 10s
Shared Java Maven CI with Docker / verify (push) Failing after 17m19s
Shared Java Maven CI with Docker / gate (push) Failing after 24s
qrun-release / release (push) Failing after 1h16m30s
qrun-release / postpublish (push) Skipped
feat(authentik): checkpoint application access and identity synchronization RC
Add user and group QQQ application-role access editing, bounded catalogs,
webhook inbox and SQL mirrors, refreshed session permissions, and deferred
invitation assignments. Include the isolated local review host, browser
acceptance scripts, documentation and the token-widget column mapping fix.

User approved this RC checkpoint. Full 1.0 gates remain documented, including
the schema-drift matcher and PostgreSQL integration errors from the full gate.
Companion UI: QRun-IO/qqq-frontend-next#205.

Co-Authored-By: GPT-6 <noreply@openai.com>
2026-11-05 05:29:54 -06:00

3.9 KiB

Host synchronization integration

MIRROR and WEBHOOK are opt-in features. The QBit producer now registers their metadata, jobs and routes. The updated local review host enables both with SQL storage; see local review for its acceptance limitations. Production rollout still requires the staging, scale, browser-session and rollback checks in the release checklist.

Before producing the QBit, the host must register its local RDBMS backend and a cron-capable scheduler. Set localBackendName and, when more than one scheduler exists, schedulerName. Enable READ and MIRROR; add WEBHOOK and resolve webhookSecret from the host secret environment to accept events. Missing dependencies or conflicting mirror table/process names fail production of the metadata. These features do not require enabling upstream administrative writes.

The host owns migrations: apply schema-sync.sql, adapting table names for the configured prefix, and the existing local schema. Register standard QQQ audit tables and possible-value sources. Enrich local tables with the host backend's physical table details before validating the instance. Mirror field metadata already supplies explicit column names. The producer makes no database or Authentik calls and does not create SQL tables. H2 and PostgreSQL have executable integration coverage; other database vendors have not been verified for synchronization.

The producer adds all seven synchronization tables: users, groups, memberships, inbox, checkpoint/lease state, durable session bindings and invitation assignment intent. Generic writes remain disabled. It registers incremental reconciliation every five minutes, full reconciliation at 02:00 UTC, daily retention and, with WEBHOOK, inbox polling every two seconds. The host starts its normal QQQ scheduler. Jobs require the internal system session and use database ownership to serialize publishers.

WEBHOOK also adds a native QJavalin route-provider reference. The host's normal QJavalin server loads it. Configure Authentik to POST with the X-QQQ-Webhook-Secret header to:

Table/component prefix Webhook path
authentik (default) /qqq/hooks/authentik/webhook
workforce /qqq/hooks/workforce/webhook
Empty /qqq/hooks/webhook

These are machine-to-machine routes, outside the versioned UI API as required by QQQ's UI API extension contract. Earlier development configuration used /qqq/v1/.../webhook; update notification transports to the paths above. No legacy alias is registered: it would fail QQQ's strict UI route audit.

Each provider is bound to its QBit API backend; credentials and feature state are resolved for every request. Multiple QBits also need distinct producer namespaces and component prefixes. Existing host route definitions are preserved. Do not register another handler on a QBit webhook path. Requests authenticate before body parsing and acknowledge only committed inbox receipts. Polling recovers failed delivery notifications.

Without esbDestinationName, committed events are processed inline. With it, register the destination and provider in the host's ESB metadata before producing the QBit, include the optional ESB dependency, and start the normal host ESB runtime. Notifications contain no event payload; SQL inbox processing remains authoritative and polling stays enabled.

Registration does not change the host's authentication module. Configure the refreshing OAuth adapter and immutable identity mapping separately after a successful baseline. Its fifteen-minute freshness ceiling is unchanged: prolonged synchronization failure denies access rather than restoring old token grants. The refreshing mapper's bounded directory-outage fallback is verified on H2 and PostgreSQL. Widget outage behavior, invitation-used assignments, operational views and production-scale acceptance remain release work.