Skip to content

Conceptos: cómo funciona la autenticación y el acceso a datos ​

Para configurar la integración de Sistema de salud es útil entender los estándares que participan. Esta página los explica de forma completa pero orientada a la operación: son los términos exactos (client_id, scope, JWK, RS384, etc.) que te van a pedir los sistemas externos.

OAuth 2.0 ​

OAuth 2.0 es un marco de autorización (RFC 6749) que permite a una aplicación obtener acceso delegado a recursos protegidos sin compartir credenciales del usuario. Es el estándar que usan la mayoría de las APIs modernas (Google, GitHub, servicios de salud, etc.).

Actores ​

ActorQué esEn esta integración
Resource ownerEl dueño de los datosLa organización (y sus pacientes)
ClientLa aplicación que quiere acceder a los datosQuralo
Authorization serverEmite los tokensEl token endpoint del sistema de salud
Resource serverGuarda y sirve los datosLa API FHIR R4 del sistema de salud

Piezas fundamentales ​

  • Access token: un "pase" temporal que prueba que el cliente está autorizado a hacer una acción. Se envía en el header Authorization: Bearer <token>. En este contexto es un JWT firmado.
  • Scope: el alcance o permiso otorgado al token (qué recursos puede leer, por ejemplo). Limita el "radio de acción" del token.
  • Grant type: el método que usa el cliente para obtener el token. En esta integración se usa client_credentials.

Tipos de grant (resumen) ​

OAuth 2.0 define varios flujos según el escenario:

GrantUso típico¿Se usa acá?
authorization_codeAplicaciones con usuario que inicia sesión (ej. "Login con Google")No
implicitSPA antiguas (deprecado)No
passwordConfiar el usuario/password al cliente (desaconsejado)No
client_credentialsComunicación máquina-a-máquina (M2M), sin usuarioSí
refresh_tokenRenovar un access token que expiróDerivado de otros flujos

Client Credentials: el flujo M2M ​

Cuando dos sistemas se hablan sin un usuario humano de por medio (por ejemplo, Quralo consultando los datos del HIS), se usa el grant Client Credentials. El cliente se autentica contra el servidor de autorización presentando sus propias credenciales de cliente, y a cambio recibe un access token con los scopes solicitados.

En un OAuth "clásico" esas credenciales son un client_id + client_secret (una contraseña compartida). Pero compartir un secreto entre organizaciones es frágil: si se filtra, hay que rotarlo, y ambos lados deben guardarlo de forma segura.

La alternativa elegida: Private Key JWT ​

En lugar de un client_secret, la integración de Quralo usa Private Key JWT (RFC 7523): el cliente firma un JWT con su clave privada y se lo presenta al servidor de autorización. El servidor verifica la firma con la clave pública que la organización registró previamente.

Ventajas:

  • No se comparte ningún secreto: la clave privada nunca viaja ni se expone.
  • Firma criptográfica: la identidad se demuestra con criptografía de clave pública, no con una contraseña.
  • Rotación controlada: se pueden regenerar los pares de claves sin coordinar un secreto nuevo con el proveedor.

¿Cómo se autentica el cliente? ​

Los métodos de autenticación de cliente que define OAuth 2.0 son variados (client_secret_basic, client_secret_post, tls_client_auth, private_key_jwt, etc.). SMART Backend Services exige private_key_jwt, que es el que implementa Quralo.

En el request de token, el cliente envía:

http
POST {token_endpoint}
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=<JWT firmado>
&scope=system/Patient.read system/Observation.read
  • client_assertion_type indica que la aserción es un JWT bearer.
  • client_assertion es el JWT firmado con la clave privada del cliente.

Estructura del client assertion JWT ​

Un JWT tiene tres partes separadas por puntos: header.payload.signature. Cada parte está codificada en Base64URL.

Header (identifica el algoritmo y la clave usada para firmar):

json
{
  "alg": "RS384",
  "kid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "typ": "JWT"
}
  • alg: algoritmo de firma. Acá RS384 (RSA) o ES384 (EC P-384).
  • kid: key ID, el identificador de la clave pública que el servidor debe usar para verificar. Es un UUID corto, estable por par de claves.

Payload (las afirmaciones sobre quién es el cliente):

json
{
  "iss": "cliente_del_his",
  "sub": "cliente_del_his",
  "aud": "https://his.ejemplo.com/fhir/token",
  "iat": 1737150000,
  "exp": 1737150060,
  "jti": "8f1c…"
}
ClaimQué es
iss (issuer)Quién emite la aserción → el client_id
sub (subject)El sujeto → también el client_id
aud (audience)Para quién es → el token endpoint
iat (issued at)Fecha/hora de emisión (unix timestamp)
exp (expiration)Expiración (corta, típicamente 1-5 min)
jti (JWT ID)Identificador único de la aserción (anti-replay)

Signature: el resultado de firmar header.payload con la clave privada. El servidor lo verifica usando la clave pública que la organización registró (identificada por el kid).

Claves y JWK / JWKS ​

Un JWK (JSON Web Key, RFC 7517) es la representación JSON de una clave criptográfica. Un JWKS (JSON Web Key Set) es una lista de claves: { "keys": [ ... ] }.

El JWK que Quralo te muestra para registrar incluye use: "sig" (la clave es para firmar/verificar firmas), alg, kid y el material criptográfico:

json
{
  "keys": [
    {
      "kty": "RSA",
      "use": "sig",
      "alg": "RS384",
      "kid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "n": "…",
      "e": "AQAB"
    }
  ]
}

Para EC P-384 (ES384) el formato usa crv, x e y:

json
{
  "kty": "EC",
  "use": "sig",
  "alg": "ES384",
  "kid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "crv": "P-384",
  "x": "…",
  "y": "…"
}

Algoritmos de firma: RS384 y ES384 ​

AlgoritmoTipo de claveObservación
RS384RSA (≥ 2048 bits)RSA con hash SHA-384. Es el recomendado y el default en Quralo. Ampliamente soportado.
ES384EC P-384 (curva elíptica)ECDSA con hash SHA-384. Claves más cortas y firmas más pequeñas, pero requiere que el servidor externo lo soporte.

SMART Backend Services exige uno de estos dos algoritmos (no acepta, por ejemplo, RS256). El que elijas debe coincidir con lo que espera tu sistema de salud.

SMART Backend Services ​

SMART (Substitutable Medical Applications, Reusable Technologies) es el estándar de interoperabilidad de aplicaciones clínicas sobre FHIR, impulsado por HL7 y Boston Children's Hospital. Tiene dos variantes:

  • SMART App Launch: para aplicaciones que corren con un usuario que autoriza (flujo authorization_code).
  • SMART Backend Services: para comunicación servidor a servidor (M2M) sin usuario, que es exactamente el caso de la integración de Quralo.

SMART Backend Services define:

  1. Autenticación del cliente: client_credentials + private_key_jwt con RS384 o ES384 (lo que ya vimos).
  2. Scopes con formato system/{recurso}.{operación} (ej. system/Patient.read). El prefijo system/ indica que el token actúa "a nombre del sistema", no de un usuario.
  3. Descubrimiento: el servidor FHIR puede publicar su configuración en .well-known/smart-configuration, donde se anuncian el token endpoint, los scopes soportados y los algoritmos.

Descubrimiento del token endpoint ​

Si el sistema externo expone .well-known/smart-configuration, Quralo descubre automáticamente el token endpoint:

http
GET {fhir_base_url}/.well-known/smart-configuration
json
{
  "token_endpoint": "https://his.ejemplo.com/fhir/token",
  "capabilities": ["permission-v2"],
  "scopes_supported": ["system/Patient.read", "system/*.read"],
  "code_challenge_methods_supported": []
}

Si tu sistema no expone este archivo, configurás el Token endpoint URL manualmente en la integración.

FHIR R4 ​

FHIR (Fast Healthcare Interoperability Resources, HL7) es el estándar moderno para intercambiar datos de salud por API. La versión R4 (Release 4) es la 4.0.1 y es la que requiere esta integración.

Recursos ​

Los datos clínicos se modelan como recursos con estructura JSON. Algunos relevantes para los scopes de Quralo:

RecursoQué representa
PatientDatos demográficos de un paciente
ObservationResultados y observaciones clínicas (laboratorio, signos vitales)
DiagnosticReportInformes de diagnóstico (imágenes, laboratorio)
MedicationRequestPrescripciones / solicitudes de medicación
ServiceRequestSolicitudes de servicio (estudios, procedimientos)
EncounterEncuentros clínicos (consultas, internaciones)
CapabilityStatementLa "tarjeta de presentación" del servidor (qué soporta)

Interacciones RESTful ​

FHIR R4 usa REST: GET, POST, PUT, DELETE sobre las colecciones de recursos (/Patient, /Observation, etc.). Esta integración consume principalmente lectura (interacciones read y search).

/metadata y el CapabilityStatement ​

Todo servidor FHIR debe responder en GET {base}/metadata con un CapabilityStatement: el documento que declara las capacidades del servidor (versión de FHIR, recursos soportados, seguridad, etc.).

El campo fhirVersion indica la versión del estándar. La verificación de Quralo exige que sea 4.0.1:

json
{
  "resourceType": "CapabilityStatement",
  "status": "active",
  "fhirVersion": "4.0.1",
  "rest": [
    {
      "mode": "server",
      "resource": [ { "type": "Patient" }, { "type": "Observation" } ],
      "security": { "service": [ { "coding": [ { "code": "SMART-on-FHIR" } ] } ] }
    }
  ]
}

La verificación consulta /metadata con el token (Authorization: Bearer <token>): así confirma que el token es aceptado contra la base FHIR correcta y que la versión es la exigida.

Scopes SMART sobre FHIR ​

Los scopes de lectura siguen el patrón system/{Recurso}.read (o system/*.read para todos los recursos). El servidor FHIR solo devuelve los recursos para los que el token tenga scope. El catálogo completo que podés configurar está en Scopes.

El flujo completo, de punta a punta ​

Resumen ​

  • OAuth 2.0 es el marco de autorización; se usa el grant client_credentials (M2M, sin usuario).
  • En lugar de un secreto compartido, el cliente se autentica con Private Key JWT: firma un JWT con su clave privada (RS384 o ES384), que el servidor verifica con la clave pública registrada.
  • SMART Backend Services es el perfil de HL7 que exige este método y define los scopes system/... y el descubrimiento por .well-known/smart-configuration.
  • FHIR R4 es la API de datos clínicos; la integración lee recursos y valida fhirVersion == 4.0.1 en /metadata.

Ahora que tenés el panorama completo, seguí con la Configuración paso a paso.

Documentación de Quralo