Architecture
High-level flow
┌──────────────┐ ┌─────────────────┐
│ labops-web │ OIDC Auth Code │ WSO2 IS │
│ (React SPA) │◄────── PKCE ────────│ rke2-dc │
└──────┬───────┘ │ is.apps... │
│ └─────────────────┘
│ Bearer token (user ctx) ▲
▼ │ Key Manager
┌──────────────┐ bearer ┌──────────────┐ │
│ APIM Gateway │─────────►│ tickets-api │────┘
│ rke2-dc │ bearer │ assets-api │
│ gateway.apps │─────────►│ (Spring Boot)│
└──────┬───────┘ └──────┬───────┘
│ │ JDBC
│ async ▼
▼ ┌──────────────┐
┌──────────────┐ │ Postgres │
│ MI flows │ │ spoke-dc │
│ rke2-dc │ └──────────────┘
│ mi.apps... │
└──┬───────────┘
│ scheduled webhook fan-out + retry/DLQ
▼ ▼
┌─────────────┐ ┌────────────────┐
│ GitLab API │ │ external sinks │
│ (issues→DB) │ │ (Slack, email) │
└─────────────┘ └────────────────┘Personas and grants
| Persona | Auth | Why |
|---|---|---|
| End user | OIDC Auth Code + PKCE via SPA | Standard human login |
| Employee | OIDC + federated Google + MFA | Demos federation and adaptive auth |
| Partner system | OAuth2 client_credentials | Demos M2M, partner subscription tier |
API security shape
| API | Resource grants | Notes |
|---|---|---|
tickets-api | OAuth2 user, scopes tickets:read, tickets:write, tickets:admin | Adaptive auth: admin scope requires MFA |
assets-api | OAuth2 client_credentials (M2M write), OAuth2 user (read) | Mediation policy adds correlation ID |
| Public read endpoints | API Key | Demos non-OAuth path + tier throttling |
Why this layout
- Platform on rke2 vs app on spoke-dc — keeps the WSO2 stack co-located with the existing infra (gitops-rke2 already manages it). The demo app lives on spoke-dc because that's the "user workload" cluster — separation matches a typical hybrid OpenShift+RKE2 enterprise setup.
- Postgres on spoke-dc, not rke2 — application data sits with the application; rke2's databases are reserved for platform services.
- Single GitHub monorepo — services + frontend + integrations + docs ship together; one CI lane, one place to grep.