Autenticação
A API IORQ usa OAuth 2.0 client_credentials. Você troca um client_id + client_secret por um Bearer JWT com validade de 1 hora e passa o token no header Authorization de cada chamada operacional. Sem sessões, sem cookies, sem refresh tokens.
POST /oauth2/token · OAuth 2.0 · JWT
1. Modelo de autenticação
A IORQ adota OAuth 2.0 client_credentials sobre Amazon Cognito — o fluxo apropriado para integrações server-to-server. Não há usuário final no caminho, não há autorização explícita por consentimento. As credenciais identificam a aplicação cliente do integrador; as permissões e os fundos acessíveis são resolvidos pela IORQ a partir do client_id.
sequenceDiagram
participant INT as Integrador
participant AUTH as IORQ Auth (Cognito)
participant API as IORQ API
INT->>AUTH: POST /oauth2/token (client_id + client_secret)
AUTH-->>INT: access_token (JWT, exp=1h)
loop Por até 1h
INT->>API: Chamada operacional (Bearer access_token)
API-->>INT: Resposta
end
Note over INT,AUTH: Após expiração, repete o /oauth2/token
2. Obter um token
2.1 POST /oauth2/token
POST /oauth2/tokenPOST /oauth2/token · application/x-www-form-urlencoded · host auth-hs.iorq.com.br (sandbox: auth-dev.iorq.com.br)
Host de autenticaçãoO token é obtido no serviço de autenticação (
https://auth-hs.iorq.com.br/oauth2/token), não no hs-receiver. As chamadas operacionais usam o hosths-receiver-app-*.iorq.com.br/api. A API do investidor usainvestor-api.iorq.com.br(sandbox:investor-api-dev.iorq.com.br), sem o prefixo/api. O token de todas elas é emitido neste mesmo host.
Parâmetros (form-encoded)
| Campo | Obrigatório | Descrição |
|---|---|---|
grant_type | sim | Sempre client_credentials |
client_id | sim | Identificador da aplicação, fornecido pela IORQ |
client_secret | sim | Secret correspondente. Trate como senha — não exponha em logs, repositórios ou frontend |
scope | não | Opcional. Escopo Cognito do resource server (ex.: cerberus-m2m/read). A autorização efetiva por endpoint é feita pela IORQ a partir do client_id, não pelo escopo |
Exemplo:
curl -X POST 'https://auth-hs.iorq.com.br/oauth2/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials' \
-d 'client_id=YOUR_CLIENT_ID' \
-d 'client_secret=YOUR_CLIENT_SECRET'Resposta:
{
"access_token": "eyJraWQiOiJyc2EtMjAyNiIsImFsZyI6IlJTMjU2In0...",
"token_type": "Bearer",
"expires_in": 3600
}2.2 Usar o token
Inclua o token no header Authorization de toda chamada operacional. O prefixo Bearer é obrigatório (com espaço). Lembre que as rotas operacionais ficam sob o prefixo /api.
curl 'https://hs-receiver-app-production.iorq.com.br/api/loan/?originator_proposal_code=OP-001' \
-H 'Authorization: Bearer eyJraWQiOiJyc2EtMjAyNiIs...'2.3 O fund_id
fund_idQuando a IORQ libera seu acesso, você recebe um e-mail de credenciais com client_id, client_secret e a lista de fundos liberados — cada um com nome e UUID. Esse UUID é o fund_id que você usa em toda a integração.
De onde vem o valorGuarde o UUID exibido no e-mail (seção Fundos liberados). Sandbox e produção têm
fund_iddiferentes — use sempre o UUID do ambiente em que está integrando.
O mesmo UUID e o mesmo header valem para todos os serviços:
| Serviço | Como informar o fundo |
|---|---|
API operacional (hs-receiver) | Header iorq-fund-id em toda requisição; em muitas rotas também no corpo ou na query como fund_id, e os dois têm de bater |
Webhooks (webhook-sender-manager) | Header iorq-fund-id em toda rota do serviço, e só por ele: não existe fund_id no corpo nem na query. O fund_id que aparece nas respostas é eco do header |
| API do investidor | Header iorq-fund-id em toda rota de fundo, e só por ele. O UUID é o id devolvido por GET /v1/funds. GET /v1/funds não recebe o header |
Exemplo na API operacional:
curl 'https://hs-receiver-app-production.iorq.com.br/api/loan/?fund_id=374485cf-f6df-467c-b91d-9f14082c6f36&originator_proposal_code=OP-001' \
-H 'Authorization: Bearer eyJraWQiOiJyc2EtMjAyNiIs...' \
-H 'iorq-fund-id: 374485cf-f6df-467c-b91d-9f14082c6f36'Exemplo no webhook-sender-manager:
curl -X POST 'https://webhook-sender-manager-production.iorq.com.br/api/webhook' \
-H 'Authorization: Bearer eyJraWQiOiJyc2EtMjAyNiIs...' \
-H 'iorq-fund-id: 374485cf-f6df-467c-b91d-9f14082c6f36' \
-H 'Content-Type: application/json' \
-d '{ "message_type": "LOAN_UPDATE", "webhook_url": "https://example.com/hooks", "contract_version": "v2" }'
Um único header de fundoO mesmo UUID e o mesmo header
iorq-fund-idvalem para os dois serviços. O exemplo acima é só para mostrar o header: o registro completo do webhook, comcontract_version: "v2"(sem ele o webhook nasce no contrato legado v1) e os demais campos, está em Configurando webhooks.
3. Perfis de acesso
O mesmo fluxo client_credentials, no mesmo host de autenticação (auth-hs.iorq.com.br; sandbox: auth-dev.iorq.com.br), serve os dois perfis de integração da IORQ. O claim scope do token muda com o perfil (cerberus-m2m/read para originador, cerberus-m2m/investor para investidor), mas não decide o acesso: as permissões e os fundos de cada credencial são resolvidos pela IORQ a partir do client_id, a cada chamada.
| Perfil | Quem é | APIs | Fundos |
|---|---|---|---|
| Originador | Originador, bancarizador ou plataforma de crédito que cede operações ao fundo | API operacional (hs-receiver-app-*.iorq.com.br/api) e Webhooks (webhook-sender-manager-*.iorq.com.br/api) | Os fundos em que a credencial opera, listados no e-mail de credenciais |
| Investidor | Gestora de um investidor institucional que tem cotas no fundo | API do investidor (investor-api.iorq.com.br), somente leitura | Os fundos em que o investidor tem cotas, listados por GET /v1/funds |
- Uma credencial, um perfil. A credencial de investidor só tem a permissão de leitura da API do investidor: ela não chama a API operacional nem a de webhooks. A credencial de originador não recebe essa permissão. Quem precisa dos dois perfis recebe duas credenciais.
- Extração de estoque (WIP), a exceção. A permissão de pedir o estoque de um fundo (
POST /v1/inventory-exports, na API do investidor) é separada da de leitura e é concedida por fundo. Ela pode ir também para a credencial de originador que é cotista do fundo, sem que essa credencial passe a ler covenants ou indicadores. Ver Extração de estoque. - O fundo vai no header. Nas duas APIs, toda rota de um fundo exige o header
iorq-fund-idcom o UUID do fundo. Na API do investidor, o UUID é oiddevolvido porGET /v1/funds. A permissão é sempre conferida no fundo do header: ter acesso a um fundo não dá acesso a outro. - Bloqueio sem perder a credencial. A IORQ pode suspender uma credencial sem apagá-la. Enquanto suspensa, o token continua sendo emitido, mas a API do investidor responde
401(CALLER_NOT_PROVISIONED); quando a suspensão é retirada, ela volta a funcionar com o mesmoclient_ideclient_secret. Uma credencial removida não volta: a IORQ emite uma nova, com outroclient_secret.
4. Ciclo de vida do token
- Validade: 1 hora (
expires_in: 3600). O claimexpdentro do JWT é a fonte da verdade — use-o para programar renovação proativa. - Renovação: não há refresh token. Para renovar, basta chamar
POST /oauth2/tokennovamente com as mesmas credenciais. - Revogação: não há endpoint público. Em caso de comprometimento, peça ao seu contato na IORQ para revogar o
client_secret— o token deixa de ser aceito imediatamente. - Múltiplos tokens válidos: permitido. Você pode emitir tokens em paralelo para escalar — não há limite enforced por essa via.
Padrão recomendadoMantenha um cache em memória do token e renove proativamente quando faltar menos de 5 minutos para expirar. Isso evita uma rajada de
401quando o token expira no meio de um lote de cessões.
5. Anatomia do JWT
O access_token é um JWT (RFC 7519) emitido e assinado (RS256) pelo Amazon Cognito. A chave pública fica no JWKS do user pool Cognito:
https://cognito-idp.us-east-1.amazonaws.com/USER_POOL_ID/.well-known/jwks.json
Claims relevantes
| Claim | Significado |
|---|---|
sub / client_id | Identificador da aplicação cliente (em tokens M2M, client_id == sub) |
scope | Escopo Cognito do resource server (ex.: cerberus-m2m/read) |
token_use | access |
exp | Timestamp UNIX de expiração |
iat | Timestamp UNIX de emissão |
iss | Emissor — o URL do user pool Cognito |
Partner e fundos não vêm no tokenO parceiro (
id_partner) e os fundos/credit vehicles acessíveis não são claims do JWT. Eles são resolvidos pela IORQ a cada chamada, a partir doclient_id, pelo serviço de autorização (Cerberus). Você não precisa verificar a assinatura do token — a IORQ valida do lado dela.
6. Segurança do client_secret
client_secret- Armazene o
client_secretem cofre de credenciais (AWS Secrets Manager, HashiCorp Vault, GCP Secret Manager). Nunca em repositório, build artifact ou variável de ambiente em plain text. - Rotacione o secret pelo menos a cada 12 meses. Em caso de qualquer suspeita, rotacione imediatamente — a IORQ emite secrets sob demanda.
- Não use o secret no frontend. O fluxo client_credentials é exclusivamente server-side.
- Restrinja o acesso ao secret aos serviços que efetivamente chamam
/oauth2/token. Cada serviço que precisa de token deve ter sua própria credencial.
7. Erros de autenticação
| HTTP | Serviço | Causa | Corpo | O que fazer |
|---|---|---|---|---|
400 | Autenticação | grant_type ausente ou diferente de client_credentials | — | Corrigir o payload da chamada a /oauth2/token |
401 | Autenticação | client_id ou client_secret inválido | — | Verificar credenciais; rotacionar se necessário |
401 | API de cessão | Token expirado, malformado ou ausente | {"message": "...", "status": 401} | Renovar via /oauth2/token e refazer |
401 | Webhooks | Só Authorization ausente | {"message": "Unauthorized"} | Incluir o header |
403 | Webhooks | Token inválido ou expirado, recusado no gateway | {"message": "Forbidden"} | Renovar via /oauth2/token e refazer; ver os formatos de erro |
400 | API de cessão | Header iorq-fund-id ausente em rota que o exige | {"detail": "..."} | Incluir o UUID do fundo no header |
400 | Webhooks | Header iorq-fund-id ausente ou fora do formato UUID | {"code": "bad_request", "message": "...", "details": null} | Incluir o UUID do fundo no header |
403 | API de cessão | Token válido, mas o client_id não tem permissão para o endpoint, ou o fundo está fora dos fundos provisionados | {"detail": "..."} | Revisar permissões/fundos contratados; pedir ao seu contato na IORQ |
403 | Webhooks | Token válido, mas o client_id não tem permissão para o endpoint, ou o fundo está fora dos fundos provisionados | {"code": "forbidden", "message": "...", "details": null} | Revisar permissões/fundos contratados; pedir ao seu contato na IORQ |
401 | API do investidor | Só Authorization ausente, recusado no gateway | {"message": "Unauthorized"} | Incluir o header |
401 | API do investidor | Credencial desconhecida, suspensa ou removida | {"message": "...", "status": 401, "error_code": "CALLER_NOT_PROVISIONED"} | Falar com o seu contato na IORQ |
403 | API do investidor | Token inválido ou expirado, recusado no gateway | {"message": "Forbidden"} | Renovar via /oauth2/token e refazer |
400 e 403 | API do investidor | Header iorq-fund-id ausente ou fora do formato UUID (400); fundo não vinculado à credencial ou sem permissão de leitura (403) | {"message": "...", "status": ..., "error_code": "..."} | Ver os erros da API do investidor |
422 | Webhooks | Corpo ou parâmetro inválido | {"code": "validation_error", "message": "...", "details": [{"loc", "msg", "type"}]} | Corrigir o campo que o msg aponta |
429 | Autenticação | Excesso de chamadas a /oauth2/token | — | Cachear o token até próximo do exp antes de renovar |
O serviço de webhooks (webhook-sender-manager) e a API do investidor ficam atrás de outros gateways e respondem ao token inválido ou expirado com 403, não 401: um cliente que só renova o token ao ver 401 fica preso no 403 lá. Trate 403 com corpo {"message": "Forbidden"} como "renove o token" em todos os serviços. A validação de corpo é 422 com code: validation_error e a lista em details no serviço de webhooks; na API de cessão os erros de validação de corpo estão em cada fluxo (Cessão de operações, Liquidação).
8. Próximos passos
Updated about 6 hours ago
