---
title: Acessos a portais
description: O agente entra em portais como o Sankhya com o login de quem o usa, sem que o usuário e a senha passem pela conversa.
sidebar:
  order: 4
---

Alguns trabalhos começam num portal que pede usuário e senha, como um ERP ou o site de um banco. O agente guarda esse acesso na Siglata uma vez e, quando precisa dele, um script na sua máquina o lê e faz o login. O usuário e a senha nunca aparecem na conversa, e ninguém precisa mantê-los num arquivo `.env`.

Cada pessoa guarda o próprio acesso. Duas pessoas podem ter cada uma o seu `sankhya`, então uma skill da empresa entra no portal como quem a executa.

## Guardar um acesso [#request]

Peça ao agente, por exemplo: "guarde o acesso ao Sankhya". Ele chama `credential_request` com um nome e os campos do login:

```js
return await credential_request({
  name: "sankhya",
  fields: ["username", "password"],
});
```

A resposta traz um link. Abra-o e digite os valores na página; se a Siglata pedir para entrar, entre e abra o link de novo. O link vale uma vez, por uma hora, e só para quem o pediu. Para trocar a senha, peça de novo com o mesmo nome: os novos valores substituem os antigos.

`credential_list` mostra os nomes, os campos, de quem é cada acesso e se ele já tem valores, nunca os valores. `isSelected: true` marca o acesso que `credential_use` usa para você.

## Skills que entram em portais [#skills]

Uma skill da empresa declara no frontmatter do `SKILL.md` os acessos de que precisa:

```yaml
---
name: extrair-pedidos-sankhya
description: Extrai os pedidos do dia do Sankhya.
credentials: [sankhya]
---
```

`skill_find` devolve essa lista em `credentials`. Antes de executar a skill, o agente confere cada nome com `credential_list` e, para cada acesso que falta, já manda o link de `credential_request` para a pessoa digitar o próprio login. Um `credentials` que não seja uma lista de nomes de acesso faz o `file_write` do `SKILL.md` falhar, apontando o campo.

## Usar um acesso [#use]

Quando um script precisa do login, o agente chama `credential_use` e entrega o endereço ao script. O token vai depois do `#` e nunca aparece no endereço de uma requisição: o script envia `{ "token" }` com um `POST` ao endereço sem o `#`:

```js
return await credential_use({ name: "sankhya" });
```

`name` leva ao seu próprio acesso com esse nome; se você não tiver um, ao acesso da empresa compartilhado com você. Se não houver nenhum dos dois, `credential_use` falha com `not_found` e o agente pede o seu com `credential_request`.

O endereço vale uma vez, por cerca de 60 segundos, e responde com `{ "name": "sankhya", "values": { "username": "…", "password": "…" } }`. Cada uso fica registrado com o acesso, a pessoa e a hora. O agente não abre o endereço nem mostra o que ele devolve.

## Quem pode usar [#access]

O acesso que `credential_request` cria é pessoal: só quem o criou pode usá-lo ou trocar os valores. Proprietários e administradores veem que ele existe (o nome, a dona, os campos e se tem valores) e podem excluí-lo quando alguém sai da organização, com `credential_delete({ credentialId })`, mas não podem usá-lo nem ler os valores. Um acesso pessoal não pode ser compartilhado.

Para um login que várias pessoas usam, um proprietário ou administrador cria o acesso da empresa com `visibility: "org"`:

```js
return await credential_request({
  name: "sankhya",
  fields: ["username", "password"],
  visibility: "org",
});
```

Ele serve a todo membro que não tem um acesso próprio com esse nome. Para deixar membros ou equipes específicos trocarem os valores, conceda escrita com `grant_set` e o `credentialId` que `credential_list` mostra. `credential_delete` apaga os valores, os links abertos e as concessões.

## Como os valores ficam guardados [#storage]

Os valores são cifrados com AES-GCM antes de chegar ao banco de dados, com uma chave própria por acesso, que por sua vez é cifrada com a chave do cofre do servidor. A organização faz parte da cifra, então um valor copiado para outra organização não abre. O banco guarda apenas o texto cifrado.
