openova/products/catalyst/bootstrap/api/internal
e3mrah 8d2a947cfb
feat(handover): auto-seed owner UserAccess CR on chroot (D21) (#1564)
Closes the D21 gap on Sovereign DoD: /users page returned empty after
fresh handover because Keycloak `sovereign-admins` membership was
established but no UserAccess CR existed for the operator.

After `keycloak.EnsureUser` succeeds in `AuthHandover`, the helper
`EnsureOwnerUserAccess` upserts a cluster-scoped UserAccess CR shaped
like the canonical user_access.go `CreateUserAccess` write:

  apiVersion: access.openova.io/v1alpha1
  kind: UserAccess
  metadata:
    name: useraccess-owner-<sanitized-email>
    annotations:
      catalyst.openova.io/user-email: <email>   # rbac_matrix:309 hint
  spec:
    user:
      keycloakSubject: <email>
    sovereignRef: <fqdn-first-label>
    applications:
      - app: "*"
        role: admin                              # owner -> admin

The Composition (issue #322) reconciles the Claim into per-app
RoleBindings on the Sovereign so the operator surfaces in /users.

Best-effort + idempotent: AlreadyExists on the second handover is
folded to nil; any other error is logged at Warn and the handover
itself never fails. If the access.openova.io CRD has not rolled yet,
the next handover retries automatically.

Architect-first: mirrors `userAccessToUnstructured` shape and uses
existing `sovereignDynamicClient` + `rbacAssignSlug` seams. Tier
mapping follows the documented lossy `owner -> admin` rule in
`userAccessTierToRole` (CRD only accepts admin|editor|viewer).

Refs: docs/SOVEREIGN-MULTI-REGION-DOD.md D21

Co-authored-by: hatiyildiz <hatice.yildiz@openova.io>
2026-05-16 23:49:32 +04:00
..
audit feat(catalyst-ui): RBAC member views — App Members tab + Org Members + access matrix + audit trail (slice U5-U8, #1098) (#1157) 2026-05-09 07:18:28 +04:00
auth feat(auth): parse groups + realm_access.roles + RBAC custom claims (slice D2, #1095) (#1118) 2026-05-08 22:56:35 +04:00
catalog fix(ui): t129 SPA routing — bp-bp- prefix, PIN /wizard leak, /app/dashboard fleet leak (#1547) 2026-05-16 20:13:26 +04:00
dynadot fix(pdm/dynadot): remove fictional ResponseHeader wrapper from api3.json adapter (#939) (#948) 2026-05-05 15:11:39 +04:00
flowemit refactor(openova-flow): CNPG-backed durable store + emit loop (#1471) 2026-05-14 14:16:11 +04:00
handler feat(handover): auto-seed owner UserAccess CR on chroot (D21) (#1564) 2026-05-16 23:49:32 +04:00
handoverjwt feat(catalyst-ui+api): replace magic-link with 6-digit PIN auth (#688) (#694) 2026-05-03 20:26:05 +04:00
helmwatch fix(helmwatch): emit Succeeded events for HRs Ready at attach time (#1510) 2026-05-15 23:54:25 +04:00
hetzner fix(purge): second name-prefix pass for CCM-named clustermesh LBs (#1532) 2026-05-16 17:29:26 +04:00
infrastructure fix(infrastructure): vCluster fallback from namespace label (D15) (#1542) 2026-05-16 19:40:50 +04:00
jobs fix(canvas): canonicalise resolved DependsOn too — kill malformed prior values (#1501) 2026-05-15 17:24:33 +04:00
jtistore feat(catalyst-api): /auth/handover endpoint for seamless single-identity flow (Closes #606) (#612) 2026-05-02 17:34:26 +04:00
k8scache fix(canvas): skip TLS verify on Sovereign k3s self-signed CA — restore sibling deps (#1497) 2026-05-15 14:46:21 +04:00
keycloak fix(catalyst-api): Keycloak admin proxy for /admin/realms/* endpoints (qa-loop iter-1 prefetch Fix #104) (#1327) 2026-05-10 22:52:34 +04:00
newapi feat(unified-rbac): SME-tier extension + host-header tenant discovery (#802) (#816) 2026-05-04 22:34:11 +04:00
objectstorage wip(#425): vendor-agnostic OS rename — partial (rate-limited mid-run) (#435) 2026-05-01 18:05:19 +04:00
openbao feat(catalyst-api): handover finalisation flow (closes #317) (#444) 2026-05-01 18:48:29 +04:00
pdm fix(catalyst-api): PDM client must add basic auth for public ingress (#907) (#908) 2026-05-05 11:07:25 +04:00
powerdns fix(dns): auto-write per-Sovereign A records into parent zone after Phase-0 (#1505) 2026-05-15 21:12:38 +04:00
provisioner fix(clustermesh): secondary cluster name match tofu scheme (D11) (#1540) 2026-05-16 19:08:55 +04:00
store fix(api): unbreak 3 pre-existing CI test failures (EPIC-0 stretch) (#1132) 2026-05-09 00:37:31 +04:00