ADORSYS-GIS / ADORSYS-GIS/ai-helm

[Epic]: Repo-as-principal auth for OpenCode — umbrella tracker (local-dev + GitLab multi-forge)

Ouverte
#591 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub
epic
Langage dominant
Go Template
Étoiles
3
Forks
1
Merge moyen
19 h 24 min
PR mergées (30 j)
80

Description

> **Umbrella tracker** for repo-scoped auth in OpenCode. **Revised 2026-07-06** to the shipped architecture (see below); the ADRs are the source of truth.

## Architecture (revised)

The work split into **two decoupled systems** once `lightbridge-authz` shipped its Identity Request Service ([authz#65](https://github.com/ADORSYS-GIS/lightbridge-authz/pull/65)) + `lightbridge-keycloak-spi`:

- **Local-dev = mint/seal (IN SCOPE, active).** `lightbridge-authz` owns projects/accounts/memberships + the IRS; `lightbridge-keycloak-spi` seals `{account_id, project_id}` into the JWT via a single-use `request_id`. The OpenCode plugin declares a `project_id` in `opencode.json` (a repo may belong to **many** projects → declared, not derived) and does a **single token exchange presenting `project_id` as a form param**; the SPI calls `resolve-context {subject, project_id}` (membership-checked) and seals `{account_id, project_id}`. Authorino + OPA enforce the project's `billing_plan`/limits from the claims. **No mint step, no `lightbridge-repo-auth`.**
- **CI = forge OIDC (DEFERRED, separate track).** GitHub CI (today) and GitLab CI (next) use **forge-minted** OIDC validated by Authorino against the **forge JWKS**, with `lightbridge-repo-auth` binding forge→**account** (account-level, since a repo maps to many projects). Does **not** use the IRS/SPI. Tracked by ADR-0078 + epic ADORSYS-GIS/ai-helm#588.

## Source of truth (links)

- `vymalo/opencode-oauth2` ADR-0005 — plugin (mint→exchange→sealed claims). *(revised)*
- `ADORSYS-GIS/ai-helm` ADR-0077 — adopt IRS+SPI for the OpenCode CLI (Keycloak `opencode-cli` client + deploy SPI + gateway reads sealed claims). *(revised, supersedes the audience-scoped draft)*
- `ADORSYS-GIS/ai-helm` ADR-0078 — GitLab CI via forge OIDC *(separate CI/forge track, deferred)*.
- Backend: [`lightbridge-authz` PR ADORSYS-GIS/ai-helm#65](https://github.com/ADORSYS-GIS/lightbridge-authz/pull/65); IdP adapter: [`lightbridge-keycloak-spi`](https://github.com/ADORSYS-GIS/lightbridge-keycloak-spi).

## Work breakdown

### ✅ In scope — local-dev mint/seal (`vymalo/opencode-oauth2` epic ADORSYS-GIS/ai-helm#64)
- [ ] vymalo/opencode-oauth2#65 — Story: local-dev requests bill to the **project** *(reword Source→project)*
- [ ] vymalo/opencode-oauth2#66 — Extract `@vymalo/opencode-auth-core` *(unchanged — still needed)*
- [ ] vymalo/opencode-oauth2#67 — Build `@vymalo/opencode-repo-auth` *(reframe: single token-exchange presenting `project_id` form param + inject sealed JWT; project_id declared in opencode.json; no mint)*
- [ ] ADORSYS-GIS/ai-helm#586 — Keycloak **`opencode-cli`** client + **deploy `lightbridge-keycloak-spi`** *(spike ANSWERED by the SPI — reframe from "exchange to Source audience")* — plus provision the basic-auth creds the SPI presents to `resolve-context`.
- [ ] ADORSYS-GIS/ai-helm-values#300 — Authorino/OPA **read sealed `{account_id, project_id}`** + enforce project plan *(reframe from "when-branch that calls /v1/resolve")*

### 🕒 Deferred — CI/forge track (`ADORSYS-GIS/ai-helm` epic ADORSYS-GIS/ai-helm#588)
- [ ] ADORSYS-GIS/lightbridge-repo-auth#3 — Provider-qualified Source identity + GitLab claims *(CI/forge only — account-level)*
- [ ] ADORSYS-GIS/lightbridge-repo-auth#4 — GitLab CI `id_tokens` setup docs
- [ ] ADORSYS-GIS/ai-helm#589 — Authorino multi-issuer GitLab OIDC trust
- [ ] ADORSYS-GIS/ai-helm#590 — `ai-helm-values` GitLab issuer list (values-repo-first)

### ❌ Closed — superseded by the shipped model
- ADORSYS-GIS/lightbridge-repo-auth#2 — "extend `/v1/resolve` for a human subject" — **superseded**: local-dev humans **mint their own `request_id`** via authz (membership-gated); repo-auth is not on the local-dev path.

### Cross-cutting — security invariant
- [ ] Internal resolve endpoints never exposed: **authz `/idp/v1/resolve-context`** is **Keycloak-only** (network-isolated, unauth — `request_id` is the credential); **repo-auth `/v1/resolve`** is **Authorino-only** (`X-Internal-Token`). No `Gateway`/`HTTPRoute`/`Ingress`/LB targets either. *(mint `POST /api/v1/idp/requests` IS public + bearer.)*
- [ ] **Open decision:** mechanize the invariant (Kyverno/Gatekeeper route check + default-deny NetworkPolicy). *(not yet ticketed)*

## Suggested sequence (in-scope)

vymalo/opencode-oauth2#66 (`auth-core`) → vymalo/opencode-oauth2#67 (plugin) alongside ADORSYS-GIS/ai-helm#586 (Keycloak client + SPI deploy) → ADORSYS-GIS/ai-helm-values#300 (gateway reads sealed claims). The CI/forge track (#588) is deferred and independent.

## Human accountable owner

@stephane-segning

## AI Usage Declaration

Research, Drafting, Ticket decomposition, Technical proposal. AI researched the shipped `lightbridge-authz`/`lightbridge-keycloak-spi` design and revised the ADRs + this tracker to match. AI output is not truth; the owner verifies.

## Human verification completed

- [ ] Intent checked against source of truth (ADR-0005/0077/0078)
- [ ] In-scope vs deferred split confirmed
- [ ] Internal-resolve invariant confirmed for both endpoints
- [x] I am the accountable owner and accept responsibility for this epic.

Guide de contribution

Ouvrir le guide de contribution

Piste de recherche

Start with ADR-0005 and ADR-0077, then read the linked child issues in the local-dev work breakdown. Trace the dependency sequence from auth-core through the plugin, Keycloak SPI deployment, and gateway values. Done means the in-scope child issues and the internal-resolve security invariant are completed; the deferred CI/forge track is not part of this work.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
gitlab, helm, kubernetes
Domaine
authentication, authorization, devops, infrastructure
Type d'issue
Fonctionnalité
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
Active
Clarté
À clarifier
Accessibilité débutants
25/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.