Skip to main content
Version: 0.4.x

Identity and Catalog

Group Format and Namespace Mapping

Pinniped relays Gitea OIDC groups as exactly two levels: orgName:teamName. This format drives namespace assignment, RBAC subject names, and role-gated actions throughout the portal.

wxops:rocket-team → namespace: tenant-wxops (org is the tenancy unit)
wxops:platform-team → platform-wide access
acme:backend-team → namespace: tenant-acme
acme:Managers → can promote acme services to staging/prod

Namespace derivation — the portal calls groupToTenant() in backend/internal/handlers/clusters.go to derive the namespace from the org segment. It never calls GET /api/v1/namespaces — for tenant users that either returns all namespaces or a 403. Namespaces are always derived from group membership instead.

RBAC subjects — ClusterRoleBindings on spoke clusters use the full orgName:teamName string as the subject, not the bare team name. This is what Pinniped Concierge impersonates after validating the cluster-scoped JWT.

Platform check — a user has platform-wide access if the teamName segment (after :) equals platform-team, regardless of orgName.

Promotion gate — lifecycle promotion to staging or production requires the user to be in platform-team or in the owning org's Managers sub-group (acme:Managers can promote services owned by the acme org).

Related

For the RBAC ClusterRole manifests applied on each spoke and the clusters.json development shortcut, see Cluster Registry.

Catalog Architecture

The portal catalog has no database and no catalog server. Entity YAML files stored in Gitea are the source of truth. The portal holds a short-lived in-memory cache so that list and detail requests do not hit Gitea on every page load.

Cache invalidation — wire a Gitea push webhook on the gitops-infra repository to POST /api/v1/webhooks/catalog/refresh (authenticated with WEBHOOK_TOKEN). On a push event the portal drops the cache immediately; the next request repopulates it from Gitea. Without the webhook, changes become visible within the 5-minute TTL.

Entity schema — entities use the backstage.io/v1alpha1 YAML schema (same apiVersion / kind / metadata / spec shape as Backstage). The portal reads them as plain YAML; no Backstage runtime is involved. See Service Catalog for the full entity kind reference and annotation conventions.