> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mka1.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Autorização

> Controle o acesso aos recursos LLM com autorização baseada em papéis. Atribua papéis de proprietário, escritor ou leitor aos usuários e verifique permissões antes de cada ação.

A API MKA1 fornece controle de acesso baseado em papéis (RBAC) em nível de recurso por meio dos endpoints de autorização.
Use esses endpoints para conceder, verificar e revogar permissões em recursos LLM para usuários específicos.

## Como funciona a autorização de recursos

Cada recurso LLM (completação, arquivo, vetor store, conversa, resposta ou habilidade) pode ter papéis atribuídos por usuário.

Três papéis formam uma hierarquia estrita:

| Papel            | Pode fazer                                                        |
| ---------------- | ----------------------------------------------------------------- |
| **proprietário** | Conceder e revogar papéis, além de tudo que o escritor pode fazer |
| **escritor**     | Modificar o recurso, além de tudo que o leitor pode fazer         |
| **leitor**       | Ler o recurso                                                     |

IDs de recursos são criados quando você faz chamadas à API LLM.
Por exemplo, criar uma conversa retorna um ID `conv_`, criar uma resposta retorna um ID `resp_`, e fazer upload de um arquivo retorna um ID `file_`.
O chamador autenticado (ou o usuário final especificado via `X-On-Behalf-Of`) torna-se automaticamente o **proprietário** desse recurso.

Use o ID do recurso retornado com os endpoints de autorização abaixo para gerenciar o acesso de outros usuários.
Somente proprietários podem conceder ou revogar papéis.
Se um não-proprietário tentar conceder ou revogar, a API retorna `403 Forbidden`.

Essas autorizações são aplicadas pelo backend do MKA1 em cada requisição.
Qualquer tentativa de ler, modificar ou excluir um recurso ao qual o chamador não tem acesso é rejeitada com uma resposta de erro apropriada.

Você também pode conceder acesso público usando `"*"` como o ID do usuário, mas apenas para os papéis `escritor` ou `leitor`.

## Conceder um papel a um usuário

Use [`POST /api/v1/authorization/llm/grant`](/pt/api-reference/resource-authorization/grant-permission-to-a-user-or-make-public) para atribuir um papel a um usuário em um recurso.
O chamador deve ser o proprietário do recurso.

<CodeGroup>
  ```bash CLI theme={null}
  mka1 permissions llm grant \
    --resource-type conversation \
    --resource-id conv-abc-123 \
    --user-id user_bob \
    --role reader \
    -H 'X-On-Behalf-Of: user_alice'
  ```

  ```ts MKA1 SDK theme={null}
  import { SDK } from '@meetkai/mka1'

  const mka1 = new SDK({ bearerAuth: 'Bearer YOUR_API_KEY' })

  // Conceder acesso de leitor ao user_bob em um recurso de conversa
  await mka1.permissions.llm.grant({
    resourceType: 'conversation',
    resourceId: 'conv-abc-123',
    userId: 'user_bob',
    role: 'reader',
  })
  ```

  ```csharp C# SDK theme={null}
  using MeetKai.MKA1;
  using MeetKai.MKA1.Types.Components;

  var sdk = new SDK(bearerAuth: "Bearer YOUR_API_KEY");

  // Conceder acesso de leitor ao user_bob em um recurso de conversa
  await sdk.Permissions.Llm.GrantAsync(new GrantPermissionRequest()
  {
      ResourceType = LlmResourceType.Conversation,
      ResourceId = "conv-abc-123",
      UserId = "user_bob",
      Role = ResourceRole.Reader,
  });
  ```

  ```python Python SDK theme={null}
  from mka1 import SDK

  sdk = SDK(bearer_auth="Bearer YOUR_API_KEY")

  # Conceder acesso de leitor ao user_bob em um recurso de conversa
  sdk.permissions.llm.grant(
      resource_type="conversation",
      resource_id="conv-abc-123",
      user_id="user_bob",
      role="reader",
  )
  ```

  ```bash bash theme={null}
  curl https://apigw.mka1.com/api/v1/authorization/llm/grant \
    --request POST \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --header 'X-On-Behalf-Of: user_alice' \
    --data '{
      "resourceType": "conversation",
      "resourceId": "conv-abc-123",
      "userId": "user_bob",
      "role": "reader"
    }'
  ```
</CodeGroup>

Uma concessão bem-sucedida retorna `204 No Content`.

O `resourceType` deve ser um dos seguintes: `completion`, `file`, `vector_store`, `conversation`, `response` ou `skill`.
O `role` deve ser um dos seguintes: `owner`, `writer` ou `reader`.

## Verificar a permissão de um usuário

Use [`GET /api/v1/authorization/llm/check`](/pt/api-reference/resource-authorization/check-user-permission) para verificar se o chamador autenticado possui um papel específico em um recurso.
A resposta contém um booleano `allowed`.

<CodeGroup>
  ```bash CLI theme={null}
  mka1 permissions llm check \
    --resource-type conversation \
    --resource-id conv-abc-123 \
    --role reader \
    -H 'X-On-Behalf-Of: user_bob'
  ```

  ```ts MKA1 SDK theme={null}
  import { SDK } from '@meetkai/mka1'

  const mka1 = new SDK({ bearerAuth: 'Bearer YOUR_API_KEY' })

  // Verificar se o chamador tem acesso de leitor
  const result = await mka1.permissions.llm.check({
    resourceType: 'conversation',
    resourceId: 'conv-abc-123',
    role: 'reader',
  })

  console.log(result.allowed) // true
  ```

  ```csharp C# SDK theme={null}
  using MeetKai.MKA1;
  using MeetKai.MKA1.Types.Components;

  var sdk = new SDK(bearerAuth: "Bearer YOUR_API_KEY");

  // Verificar se o chamador tem acesso de leitor
  var result = await sdk.Permissions.Llm.CheckAsync(
      resourceType: LlmResourceType.Conversation,
      resourceId: "conv-abc-123",
      role: ResourceRole.Reader
  );

  Console.WriteLine(result.Allowed); // true
  ```

  ```python Python SDK theme={null}
  # Verificar se o chamador tem acesso de leitor
  result = sdk.permissions.llm.check(
      resource_type="conversation",
      resource_id="conv-abc-123",
      role="reader",
  )

  print(result.allowed)  # True
  ```

  ```bash bash theme={null}
  curl "https://apigw.mka1.com/api/v1/authorization/llm/check?resourceType=conversation&resourceId=conv-abc-123&role=reader" \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --header 'X-On-Behalf-Of: user_bob'
  ```
</CodeGroup>

```json theme={null}
{ "allowed": true }
```

Como os papéis são hierárquicos, um proprietário também passa em uma verificação de `reader` ou `writer`.

## Revogar um papel

Use [`POST /api/v1/authorization/llm/revoke`](/pt/api-reference/resource-authorization/revoke-permission-from-a-user-or-remove-public-access) para remover um papel de um usuário.
Apenas o proprietário do recurso pode revogar.

<CodeGroup>
  ```bash CLI theme={null}
  mka1 permissions llm revoke \
    --resource-type conversation \
    --resource-id conv-abc-123 \
    --user-id user_bob \
    --role reader \
    -H 'X-On-Behalf-Of: user_alice'
  ```

  ```ts MKA1 SDK theme={null}
  import { SDK } from '@meetkai/mka1'

  const mka1 = new SDK({ bearerAuth: 'Bearer YOUR_API_KEY' })

  // Revogar acesso de leitor do user_bob
  await mka1.permissions.llm.revoke({
    resourceType: 'conversation',
    resourceId: 'conv-abc-123',
    userId: 'user_bob',
    role: 'reader',
  })
  ```

  ```csharp C# SDK theme={null}
  using MeetKai.MKA1;
  using MeetKai.MKA1.Types.Components;

  var sdk = new SDK(bearerAuth: "Bearer YOUR_API_KEY");

  // Revogar acesso de leitor do user_bob
  await sdk.Permissions.Llm.RevokeAsync(new RevokePermissionRequest()
  {
      ResourceType = LlmResourceType.Conversation,
      ResourceId = "conv-abc-123",
      UserId = "user_bob",
      Role = ResourceRole.Reader,
  });
  ```

  ```python Python SDK theme={null}
  # Revogar acesso de leitor do user_bob
  sdk.permissions.llm.revoke(
      resource_type="conversation",
      resource_id="conv-abc-123",
      user_id="user_bob",
      role="reader",
  )
  ```

  ```bash bash theme={null}
  curl https://apigw.mka1.com/api/v1/authorization/llm/revoke \
    --request POST \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --header 'X-On-Behalf-Of: user_alice' \
    --data '{
      "resourceType": "conversation",
      "resourceId": "conv-abc-123",
      "userId": "user_bob",
      "role": "reader"
    }'
  ```
</CodeGroup>

Uma revogação bem-sucedida retorna `204 No Content`.

## Conceder acesso público

Conceda um papel a todos os usuários autenticados definindo `userId` como `"*"`.
O acesso público é restrito aos papéis `writer` e `reader` — você não pode tornar alguém proprietário público.

<CodeGroup>
  ```bash CLI theme={null}
  mka1 permissions llm grant \
    --resource-type conversation \
    --resource-id conv-abc-123 \
    --user-id '*' \
    --role reader
  ```

  ```ts MKA1 SDK theme={null}
  await mka1.permissions.llm.grant({
    resourceType: 'conversation',
    resourceId: 'conv-abc-123',
    userId: '*',
    role: 'reader',
  })
  ```

  ```csharp C# SDK theme={null}
  using MeetKai.MKA1;
  using MeetKai.MKA1.Types.Components;

  var sdk = new SDK(bearerAuth: "Bearer YOUR_API_KEY");

  await sdk.Permissions.Llm.GrantAsync(new GrantPermissionRequest()
  {
      ResourceType = LlmResourceType.Conversation,
      ResourceId = "conv-abc-123",
      UserId = "*",
      Role = ResourceRole.Reader,
  });
  ```

  ```python Python SDK theme={null}
  sdk.permissions.llm.grant(
      resource_type="conversation",
      resource_id="conv-abc-123",
      user_id="*",
      role="reader",
  )
  ```

  ```bash bash theme={null}
  curl https://apigw.mka1.com/api/v1/authorization/llm/grant \
    --request POST \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --data '{
      "resourceType": "conversation",
      "resourceId": "conv-abc-123",
      "userId": "*",
      "role": "reader"
    }'
  ```
</CodeGroup>

## Lidar com erros de autorização

Quando um não-proprietário tenta conceder ou revogar, a API retorna `403 Forbidden`:

```json theme={null}
{
  "error": "Forbidden",
  "message": "Only resource owners can grant or revoke permissions"
}
```

Sempre verifique o papel do chamador antes de tentar alterar permissões, ou trate a resposta 403 em sua aplicação.

## Exemplo de ponta a ponta: dois usuários com papéis diferentes

Este passo a passo demonstra perfis de usuários distintos com permissões diferenciadas.
Alice cria uma conversa (tornando-se proprietária), depois concede acesso de leitura a Bob.
Verificamos que Bob pode ler mas não pode escrever, e que Bob não pode conceder permissões a outros.

<CodeGroup>
  ```bash CLI theme={null}
  # Passo 1 — Alice cria uma conversa (ela se torna a proprietária)
  CONV_JSON=$(mka1 llm conversations create \
    --body '{ "metadata": { "project": "acme" } }' \
    -H 'X-On-Behalf-Of: user_alice' \
    -o json)
  RESOURCE_ID=$(echo "$CONV_JSON" | jq -r '.id')

  # Passo 2 — Alice concede acesso de leitura a Bob
  mka1 permissions llm grant \
    --resource-type conversation \
    --resource-id "$RESOURCE_ID" \
    --user-id user_bob \
    --role reader \
    -H 'X-On-Behalf-Of: user_alice'

  # Passo 3 — Verifique que Bob tem acesso de leitura (allowed: true)
  mka1 permissions llm check \
    --resource-type conversation \
    --resource-id "$RESOURCE_ID" \
    --role reader \
    -H 'X-On-Behalf-Of: user_bob'

  # Passo 3b — Verifique que Bob NÃO tem acesso de escrita (allowed: false)
  mka1 permissions llm check \
    --resource-type conversation \
    --resource-id "$RESOURCE_ID" \
    --role writer \
    -H 'X-On-Behalf-Of: user_bob'

  # Passo 4 — Bob tenta conceder (retorna 403 Forbidden)
  mka1 permissions llm grant \
    --resource-type conversation \
    --resource-id "$RESOURCE_ID" \
    --user-id user_charlie \
    --role reader \
    -H 'X-On-Behalf-Of: user_bob'

  # Passo 5 — Alice revoga o acesso de Bob
  mka1 permissions llm revoke \
    --resource-type conversation \
    --resource-id "$RESOURCE_ID" \
    --user-id user_bob \
    --role reader \
    -H 'X-On-Behalf-Of: user_alice'

  # Passo 6 — Verifique que Bob agora está negado (allowed: false)
  mka1 permissions llm check \
    --resource-type conversation \
    --resource-id "$RESOURCE_ID" \
    --role reader \
    -H 'X-On-Behalf-Of: user_bob'
  ```

  ```ts MKA1 SDK theme={null}
  import { SDK } from '@meetkai/mka1'

  const mka1 = new SDK({ bearerAuth: 'Bearer YOUR_API_KEY' })

  // Passo 1 — Alice cria uma conversa (ela se torna a proprietária)
  const conv = await mka1.llm.conversations.create(
    { metadata: { project: 'acme' } },
    { headers: { 'X-On-Behalf-Of': 'user_alice' } }
  )
  const resourceId = conv.id

  // Passo 2 — Alice concede acesso de leitura a Bob
  await mka1.permissions.llm.grant(
    {
      resourceType: 'conversation',
      resourceId,
      userId: 'user_bob',
      role: 'reader',
    },
    { headers: { 'X-On-Behalf-Of': 'user_alice' } }
  )

  // Passo 3 — Verifique as permissões de Bob
  // Bob tem acesso de leitura → permitido
  const bobReader = await mka1.permissions.llm.check(
    {
      resourceType: 'conversation',
      resourceId,
      role: 'reader',
    },
    { headers: { 'X-On-Behalf-Of': 'user_bob' } }
  )
  console.log('Bob reader:', bobReader.allowed) // true

  // Bob NÃO tem acesso de escrita → negado
  const bobWriter = await mka1.permissions.llm.check(
    {
      resourceType: 'conversation',
      resourceId,
      role: 'writer',
    },
    { headers: { 'X-On-Behalf-Of': 'user_bob' } }
  )
  console.log('Bob writer:', bobWriter.allowed) // false

  // Passo 4 — Bob tenta conceder (falha com 403)
  try {
    await mka1.permissions.llm.grant(
      {
        resourceType: 'conversation',
        resourceId,
        userId: 'user_charlie',
        role: 'reader',
      },
      { headers: { 'X-On-Behalf-Of': 'user_bob' } }
    )
  } catch (err) {
    console.log('Bob grant rejected:', err.statusCode) // 403
  }

  // Passo 5 — Alice revoga o acesso de Bob
  await mka1.permissions.llm.revoke(
    {
      resourceType: 'conversation',
      resourceId,
      userId: 'user_bob',
      role: 'reader',
    },
    { headers: { 'X-On-Behalf-Of': 'user_alice' } }
  )

  // Passo 6 — Verifique que Bob agora está negado
  const bobAfterRevoke = await mka1.permissions.llm.check(
    {
      resourceType: 'conversation',
      resourceId,
      role: 'reader',
    },
    { headers: { 'X-On-Behalf-Of': 'user_bob' } }
  )
  console.log('Bob after revoke:', bobAfterRevoke.allowed) // false
  ```

  ```csharp C# SDK theme={null}
  using MeetKai.MKA1;
  using MeetKai.MKA1.Types.Components;

  var sdk = new SDK(bearerAuth: "Bearer YOUR_API_KEY");

  // Passo 1 — Crie uma conversa (o chamador se torna o proprietário)
  var conv = await sdk.Llm.Conversations.CreateAsync(new CreateConversationRequest()
  {
      Metadata = new Dictionary<string, string> { { "project", "acme" } },
  });
  var resourceId = conv.ConversationObject!.Id;

  // Passo 2 — Conceda acesso de leitura a Bob
  await sdk.Permissions.Llm.GrantAsync(new GrantPermissionRequest()
  {
      ResourceType = LlmResourceType.Conversation,
      ResourceId = resourceId,
      UserId = "user_bob",
      Role = ResourceRole.Reader,
  });

  // Passo 3 — Verifique a permissão de Bob
  var bobReader = await sdk.Permissions.Llm.CheckAsync(
      LlmResourceType.Conversation, resourceId, ResourceRole.Reader);

  // Passo 4 — Revogue o acesso de Bob
  await sdk.Permissions.Llm.RevokeAsync(new RevokePermissionRequest()
  {
      ResourceType = LlmResourceType.Conversation,
      ResourceId = resourceId,
      UserId = "user_bob",
      Role = ResourceRole.Reader,
  });
  ```

  ```python Python SDK theme={null}
  # Passo 1 — Alice cria uma conversa (ela se torna a proprietária)
  conv = sdk.llm.conversations.create(
      metadata={"project": "acme"},
      http_headers={"X-On-Behalf-Of": "user_alice"},
  )
  resource_id = conv.id

  # Passo 2 — Alice concede acesso de leitura a Bob
  sdk.permissions.llm.grant(
      resource_type="conversation",
      resource_id=resource_id,
      user_id="user_bob",
      role="reader",
      http_headers={"X-On-Behalf-Of": "user_alice"},
  )

  # Passo 3 — Verifique as permissões de Bob
  # Bob tem acesso de leitura -> permitido
  bob_reader = sdk.permissions.llm.check(
      resource_type="conversation",
      resource_id=resource_id,
      role="reader",
      http_headers={"X-On-Behalf-Of": "user_bob"},
  )
  print("Bob reader:", bob_reader.allowed)  # True

  # Bob NÃO tem acesso de escrita -> negado
  bob_writer = sdk.permissions.llm.check(
      resource_type="conversation",
      resource_id=resource_id,
      role="writer",
      http_headers={"X-On-Behalf-Of": "user_bob"},
  )
  print("Bob writer:", bob_writer.allowed)  # False

  # Passo 4 — Bob tenta conceder (falha com 403)
  try:
      sdk.permissions.llm.grant(
          resource_type="conversation",
          resource_id=resource_id,
          user_id="user_charlie",
          role="reader",
          http_headers={"X-On-Behalf-Of": "user_bob"},
      )
  except Exception as err:
      print("Bob grant rejected:", err)  # 403

  # Passo 5 — Alice revoga o acesso de Bob
  sdk.permissions.llm.revoke(
      resource_type="conversation",
      resource_id=resource_id,
      user_id="user_bob",
      role="reader",
      http_headers={"X-On-Behalf-Of": "user_alice"},
  )

  # Passo 6 — Verifique que Bob agora está negado
  bob_after_revoke = sdk.permissions.llm.check(
      resource_type="conversation",
      resource_id=resource_id,
      role="reader",
      http_headers={"X-On-Behalf-Of": "user_bob"},
  )
  print("Bob after revoke:", bob_after_revoke.allowed)  # False
  ```

  ```bash bash theme={null}
  # Passo 1 — Alice cria uma conversa (ela se torna a proprietária)
  CONV=$(curl -s https://apigw.mka1.com/api/v1/llm/conversations \
    --request POST \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --header 'X-On-Behalf-Of: user_alice' \
    --data '{ "metadata": { "project": "acme" } }')
  RESOURCE_ID=$(echo "$CONV" | jq -r '.id')

  # Passo 2 — Alice concede acesso de leitura a Bob
  curl https://apigw.mka1.com/api/v1/authorization/llm/grant \
    --request POST \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --header 'X-On-Behalf-Of: user_alice' \
    --data "{
      \"resourceType\": \"conversation\",
      \"resourceId\": \"$RESOURCE_ID\",
      \"userId\": \"user_bob\",
      \"role\": \"reader\"
    }"

  # Passo 3 — Verifique que Bob tem acesso de leitura (allowed: true)
  curl "https://apigw.mka1.com/api/v1/authorization/llm/check?resourceType=conversation&resourceId=$RESOURCE_ID&role=reader" \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --header 'X-On-Behalf-Of: user_bob'

  # Passo 3b — Verifique que Bob NÃO tem acesso de escrita (allowed: false)
  curl "https://apigw.mka1.com/api/v1/authorization/llm/check?resourceType=conversation&resourceId=$RESOURCE_ID&role=writer" \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --header 'X-On-Behalf-Of: user_bob'

  # Passo 4 — Bob tenta conceder (retorna 403 Forbidden)
  curl -s -o /dev/null -w "%{http_code}" \
    https://apigw.mka1.com/api/v1/authorization/llm/grant \
    --request POST \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --header 'X-On-Behalf-Of: user_bob' \
    --data "{
      \"resourceType\": \"conversation\",
      \"resourceId\": \"$RESOURCE_ID\",
      \"userId\": \"user_charlie\",
      \"role\": \"reader\"
    }"
  # Saída: 403

  # Passo 5 — Alice revoga o acesso de Bob
  curl https://apigw.mka1.com/api/v1/authorization/llm/revoke \
    --request POST \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --header 'X-On-Behalf-Of: user_alice' \
    --data "{
      \"resourceType\": \"conversation\",
      \"resourceId\": \"$RESOURCE_ID\",
      \"userId\": \"user_bob\",
      \"role\": \"reader\"
    }"

  # Passo 6 — Verifique que Bob agora está negado (allowed: false)
  curl "https://apigw.mka1.com/api/v1/authorization/llm/check?resourceType=conversation&resourceId=$RESOURCE_ID&role=reader" \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --header 'X-On-Behalf-Of: user_bob'
  ```
</CodeGroup>

## Próximos passos

* Revise o guia de [Autenticação](/pt/docs/authentication) para uso de chave de API e JWT.
* Referência da API para os endpoints de autorização:
  * [`POST /api/v1/authorization/llm/grant`](/pt/api-reference/resource-authorization/grant-permission-to-a-user-or-make-public) — Conceder um papel
  * [`POST /api/v1/authorization/llm/revoke`](/pt/api-reference/resource-authorization/revoke-permission-from-a-user-or-remove-public-access) — Revogar um papel
  * [`GET /api/v1/authorization/llm/check`](/pt/api-reference/resource-authorization/check-user-permission) — Verificar permissão
