mig: add issuance selection profiles for headless callers
Merged
DA
4d ago+176+176+012345678901234567890123456789-1-1-0123456789
AIM-597 (1 of 2)
Stacked on #8040.
Summary
- New table
issuance_selection_profiles: one profile per user session issuer and headless caller. The caller is either a client (user_session_client_id) or a workload subject (workload_issuer_id+workload_subject). Each is unique among live rows. Application code enforces that exactly one is set; no cross-column CHECK, per the repo's schema rules. - Tenancy is pinned with composite foreign keys:
(organization_id, project_id)→projects (organization_id, id).(organization_id, workload_issuer_id)→workload_issuers (organization_id, id).(user_session_issuer_id, user_session_client_id)→user_session_clients (user_session_issuer_id, id), so a profile's client always belongs to its issuer.
- The issuer itself keeps a plain FK, because project-scoped issuers do not always carry
organization_id. The next PR's API checks the issuer is the organization's before writing. - The client FK needs a new unique index,
user_session_clients (user_session_issuer_id, id). Atlas emits itCONCURRENTLY, which makes this migration-- atlas:txmode none. The new table is empty and its constraints are declared insideCREATE TABLE, so there is no PG305/PG306 scan. - The profile's choices are
upstream_client_selectionsrows of credential kindissuance_profilethat name the profile, so there is no second choices table. In the next PR, issuance copies the choices that still validate onto each new session. - Schema, migration,
atlas.sumand sqlc models only. Nothing reads or writes the table yet.
Motivation
RFC section 7.7, "Standard grant compatibility": unmodified jwt-bearer clients and workloads can't send per-server choices. Instead, an admin configures a profile scoped to the authenticated client or workload and the target sign-in, and its validated choices are copied onto each issued session.