openapi: 3.0.3
info:
  title: Unico IDCloud — Authentication
  description: |
    Endpoint de autenticação OAuth2 para obtenção do **Bearer token JWT** usado nas APIs Web & SDK (by Unico) e API (by Client) do IDCloud.

    ## Quando usar este endpoint

    Antes de qualquer chamada às APIs:

    - [`POST /client/v1/process`](./web-sdk/post-process)
    - [`POST /processes/v1`](./api/post-processes)
    - Qualquer endpoint `GET /...` consultando dados de processo.

    Você precisa obter um **access-token** chamando este endpoint.

    > **Magic Link México (Trully.ai)** usa um esquema diferente — autenticação via header `x-api-key`. Não é necessário obter token OAuth para Magic Link.

    ## Fluxo OAuth2 — JWT Bearer Grant Type

    A Unico usa o grant type `urn:ietf:params:oauth:grant-type:jwt-bearer` (RFC 7523). O fluxo simplificado:

    1. Você gera um JWT assinado (assertion) no seu backend, usando uma chave privada provisionada pela Unico.
    2. Faz `POST /oauth2/token` enviando o assertion.
    3. Recebe um `access_token` JWT válido por `expires_in` segundos (geralmente 3600).
    4. Usa o `access_token` no header `Authorization: Bearer {access_token}` das chamadas da API.

    ## ⚠️ Segurança crítica

    - O JWT assertion **deve ser gerado no backend** — nunca no frontend.
    - A chave privada **nunca** deve ser exposta em código cliente, repositórios públicos ou logs.
    - O access-token tem validade limitada — implemente refresh automático.

  version: '1.0.0'
  contact:
    name: Unico Developer Support
    url: https://devcenter.unico.io
servers:
  - url: https://identity.acesso.io
    description: Produção
  - url: https://identityhomolog.acesso.io
    description: Sandbox / UAT
tags:
  - name: Autenticação
    description: Endpoints de obtenção de token de acesso.

security:
  - JWTBearerAuth: []

paths:
  /oauth2/token:
    post:
      summary: Obter access-token
      description: |
        Endpoint para obter o access-token JWT via JWT Bearer Grant Type.

        ## Geração do JWT assertion

        O assertion é um JWT assinado (formato JWS — JSON Web Signature) com exatamente as claims abaixo. Qualquer campo extra causa erro `1.2.22`.

        ```json
        {
          "iss": "<account_name>@<tenant_id>.iam.acesso.io",
          "aud": "https://identity.acesso.io",
          "scope": "*",
          "iat": 1738086000,
          "exp": 1738089600
        }
        ```

        Algoritmo: `RS256` (RSA + SHA-256) com a chave privada `.pem` provisionada pela Unico.

        ## Exemplo de uso

        ```bash
        curl -X POST https://identity.acesso.io/oauth2/token \
          -H "Content-Type: application/x-www-form-urlencoded" \
          -d "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \
          -d "assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
        ```

        Response esperado (HTTP 200):

        ```json
        {
          "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
          "expires_in": 3600,
          "token_type": "Bearer"
        }
        ```
      operationId: obterTokenJwt
      tags:
        - Autenticação
      security:
        - JWTBearerAuth: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required:
                - grant_type
                - assertion
              properties:
                grant_type:
                  type: string
                  description: |
                    Tipo de grant. **Sempre** o valor abaixo para integração JWT Bearer.
                  example: 'urn:ietf:params:oauth:grant-type:jwt-bearer'
                assertion:
                  type: string
                  description: |
                    JWT assinado em formato compactado (JWS).
                    Gerado no seu backend com a chave privada provisionada pela Unico.
                  example: 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...'
      responses:
        '200':
          description: Access-token JWT obtido com sucesso.
          content:
            application/json:
              schema:
                type: object
                properties:
                  access_token:
                    type: string
                    description: |
                      Token JWT a ser usado no header `Authorization: Bearer {access_token}`.
                    example: 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...'
                  expires_in:
                    type: integer
                    description: Tempo de expiração em segundos.
                    example: 3600
                  token_type:
                    type: string
                    description: Tipo do token. Sempre `Bearer`.
                    example: Bearer
        '401':
          description: |
            Não autorizado. Códigos de erro comuns no campo `error_description`:

            | Código | Causa | Ação |
            |--------|-------|------|
            | `1.0.1` | Tenant ID incorreto no `iss` | Confirme o tenant ID das credenciais |
            | `1.1.1` | Claim `scope` ausente | Adicione `"scope": "*"` ao payload |
            | `1.2.4` | JWT expirado | Verifique o campo `exp` |
            | `1.2.5` | Falha na validação da assinatura | Confirme o algoritmo RS256 e a chave privada |
            | `1.2.7` | JWT já utilizado | Gere um novo assertion para cada requisição |
            | `1.2.22` | Campos não permitidos no payload | Remova claims extras (`sub`, `jti`, etc.) |
            | `1.3.1` | Restrição de IP | IP não está na allowlist da conta |
            | `1.3.2` | Restrição de horário | Requisição fora da janela permitida |
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: server_error
                  error_description:
                    type: string
                    example: 'Falha na autenticação (1.2.5)'

components:
  securitySchemes:
    JWTBearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        Token JWT obtido via `POST /oauth2/token`. Enviar no header `Authorization: Bearer {access_token}`.
