Acessos a portais
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.
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
Peça ao agente, por exemplo: “guarde o acesso ao Sankhya”. Ele chama credential_request com um nome e os campos do login:
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
Uma skill da empresa declara no frontmatter do SKILL.md os acessos de que precisa:
---
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
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 #:
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
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":
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
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.