Implementation Plan
Implementación
Plan de Implementación en fases:
Fase 1 — Keycloak (sin código, solo configuración)
1.1 Realm roles
iris_admin · bioinformatician · employee
org_member · patient · anon
1.2 Groups
/iris-internal/
bioinformatician (all_orgs=false)
bioinformatician-admin (all_orgs=true)
employee
/orgs/{org_id}/
admin
clinician
requester
viewer
/patients/ (sin sub_role, solo role=patient)
1.3 Protocol Mappers (en el realm, heredados por todos los clients)
group-membership → claim "groups"
user-attribute → claim "org_id" (del grupo)
user-attribute → claim "sub_role" (del grupo)
user-attribute → claim "all_orgs" (del grupo, boolean)
realm-roles → claim "role" (el rol de Postgres)
1.4 Clients
iris-api resource server, bearer-only
iris-genomics-cli device_flow + client_credentials (service accounts ON)
backapp-genomics authorization_code + PKCE
backapp-erm authorization_code + PKCE
crm authorization_code + PKCE
Fase 2 — Postgres + PostgREST
2.1 Roles de Postgres
CREATE ROLE authenticator (login, password, noinherit)
CREATE ROLE anon
CREATE ROLE iris_admin
CREATE ROLE bioinformatician
CREATE ROLE employee
CREATE ROLE org_member
CREATE ROLE patient
GRANT anon, iris_admin, bioinformatician,
employee, org_member, patient
TO authenticator
2.2 postgrest.conf
jwt-secret = "<keycloak-realm-public-key>"
jwt-aud = "iris-api"
db-anon-role = "anon"
2.3 RLS policies base
Una tabla de prueba con policies que lean
current_setting('request.jwt.claims')
para validar que el JWT de Keycloak llega bien
Fase 3 — iris.api (FastAPI)
3.1 Dependencias de validación
python-jose o authlib
JWKS endpoint de Keycloak (autodiscovery via /.well-known)
3.2 dependencies.py
get_current_user() — valida JWT, extrae claims
require_role() — decorator por rol
require_org() — valida org_id del token vs recurso
3.3 routers/auth.py
GET /auth/userinfo — proxy a Keycloak userinfo
POST /auth/token — proxy a Keycloak token endpoint
(para que los clients no necesiten saber
la URL de Keycloak directamente)
3.4 routers/users.py
CRUD de usuarios vía Keycloak Admin API
asignación de grupos (= asignación de org y sub_role)
3.5 routers/genomics.py
endpoints que usan iris.genomics como librería
protegidos con require_role(bioinformatician)
Fase 4 — iris.genomics
4.1 use_cases/filter_variants.py
función pura: VcfReader + VariantFilter → Iterator[VariantAnnotation]
4.2 use_cases/annotate_vcf.py
función pura: variantes + [Annotator] → Iterator[VariantAnnotation]
4.3 commands/vcf.py
CLI wrapper de filter_variants y annotate_vcf
con Typer
4.4 cli.py
entrypoint con auth: lee token de ~/.iris/credentials
(guardado por device_flow o client_credentials)
Fase 5 — BACKAPPs y CRM
5.1 genomx — explorer + auth middleware Bottle
5.2 erm — employees + orgs
5.3 crm — org_portal + patients
¿Arrancamos con la Fase 1 — la configuración de Keycloak? Puedo guiarte paso a paso: primero los realm roles, luego la jerarquía de grupos con sus atributos, y finalmente los protocol mappers que son la parte más delicada porque de ellos depende que el JWT salga con los claims correctos para PostgREST.