{“content”:“Estou vendo um comportamento inconsistente na nomenclatura de credenciais no n8n e quero confirmar se isso é esperado.\n\n### O que observo\n\n* Para meu tipo de credencial personalizado (myApi), novas credenciais são nomeadas automaticamente globalmente em toda a instância:\n\n * Usuário A cria credenciais pessoais: MyApi Account, MyApi Account 2\n\n * Usuário B (que não consegue ver as credenciais pessoais do Usuário A) cria uma e recebe: MyApi Account 3\n\n* Mas por exemplo para credenciais OpenAI, o contador parece ser pessoal/com escopo de projeto (não continua das credenciais de outros usuários da mesma forma).\n\n### Por que isso é confuso\n\nA visibilidade de credenciais é pessoal/baseada em projeto, mas o sufixo de nome gerado para meu tipo personalizado parece usar um contador global. Isso faz com que a nomenclatura pareça “vazar” entre usuários, mesmo que as credenciais não sejam compartilhadas.\n\n### Pergunta\n\n* Essa diferença entre tipos de credenciais integrados (por exemplo, OpenAI) e personalizados é esperada?\n\n* Existem múltiplos fluxos de criação de credenciais/geração de nomes no n8n que explicam isso?\n\n* Há alguma maneira de um tipo de credencial personalizado usar geração de nomes por usuário/por projeto em vez de sufixação global?\n\n\"n8n-workflow\": \"^1.120.13\"”,“target_locale”:“pt_BR”}
Bem vindo à comunidade n8n @Jankaz
você chegou a verificar se a credencial openai está sendo criada pelo mesmo fluxo que a sua credencial customizada (projeto pessoal vs projeto compartilhado vs projeto global do owner)?
Tenho para mim que o seu problema é no caminho interno de criação/nomeação que está sendo usado. consegue compartilhar um repro simples comparando custom credential vs OpenAI credential, incluindo projeto, role do usuário, nomes gerados e comportamento da numeração entre usuários?
Verifiquei as requisições na network e ambas usam https://n8n.stg.olx.org/rest/credentials com a mesma estrutura de payload. Ambas com o mesmo projectId. A única diferença é que o payload do openai tem um campo adicional uiContext: "credentials_list", mas acho que não é o caso
MyApi.credentials.ts
export class MyApi implements ICredentialType {
name = "myApi";
displayName = "My API";
properties: INodeProperties[] = [
{
displayName: "URL Base da Plataforma",
name: "baseUrl",
type: "string",
default: "http://myapi.com",
placeholder: "http://myapi.com",
required: true,
hint: "Clique em `Salvar` para autenticar.",
description: "",
},
{
displayName: "Segredo",
name: "adminToken",
type: "hidden",
typeOptions: {
password: true,
},
default: "",
description:
"Preenchido através de substituições de credenciais n8n.",
},
];
test: ICredentialTestRequest = {
request: {
method: "GET",
baseURL: "={{$credentials.baseUrl}}",
url: "/health",
},
};
}
import type {
ICredentialDataDecryptedObject,
ICredentialTestRequest,
ICredentialType,
IHttpRequestOptions,
INodeProperties,
} from 'n8n-workflow';
export class OpenAiApi implements ICredentialType {
name = 'openAiApi';
displayName = 'OpenAI';
documentationUrl = 'openai';
properties: INodeProperties[] = [
{
displayName: 'Chave de API',
name: 'apiKey',
type: 'string',
typeOptions: { password: true },
required: true,
default: '',
},
{
displayName: 'ID da Organização (opcional)',
name: 'organizationId',
type: 'string',
default: '',
hint: 'Necessário apenas se você pertencer a várias organizações',
description:
"Para usuários que pertencem a várias organizações, você pode definir qual organização é usada para uma solicitação de API. O uso dessas solicitações de API será contabilizado na cota de assinatura da organização especificada.",
},
{
displayName: 'URL Base',
name: 'url',
type: 'string',
default: 'https://api.openai.com/v1',
description: 'Substitua a URL base padrão para a API',
},
{
displayName: 'Adicionar Cabeçalho Personalizado',
name: 'header',
type: 'boolean',
default: false,
},
{
displayName: 'Nome do Cabeçalho',
name: 'headerName',
type: 'string',
displayOptions: {
show: {
header: [true],
},
},
default: '',
},
{
displayName: 'Valor do Cabeçalho',
name: 'headerValue',
type: 'string',
typeOptions: {
password: true,
},
displayOptions: {
show: {
header: [true],
},
},
default: '',
},
];
test: ICredentialTestRequest = {
request: {
baseURL: '={{$credentials?.url}}',
url: '/models',
},
};
async authenticate(
credentials: ICredentialDataDecryptedObject,
requestOptions: IHttpRequestOptions,
): Promise<IHttpRequestOptions> {
requestOptions.headers ??= {};
requestOptions.headers['Authorization'] = `Bearer ${credentials.apiKey}`;
requestOptions.headers['OpenAI-Organization'] = credentials.organizationId;
if (
credentials.header &&
typeof credentials.headerName === 'string' &&
credentials.headerName &&
typeof credentials.headerValue === 'string'
) {
requestOptions.headers[credentials.headerName] = credentials.headerValue;
}
return requestOptions;
}
}
@Jankaz
Pelo código do backend, parece que o POST /rest/credentials persiste o name recebido no payload, então eu investigaria a geração do nome no frontend antes da requisição ser enviada. Se OpenAI e a credencial customizada chegam ao mesmo endpoint com o mesmo projectId, mas já com nomes diferentes, a diferença provavelmente está no fluxo de UI que calcula o default credential name, não no save() do backend.
Obrigado - concordo que POST `/rest/credential` apenas salva o nome fornecido.
Nos rastreios de rede, tanto a credencial OpenAI quanto a customizada também chamam `GET /rest/credentials/new?name=…` antes do POST.
Então a nomeação parece ser determinada por (a) nome base do frontend + (b) geração de nome único no backend em /credentials/new.
Isso sugere que a diferença vem da correspondência de nomes existentes para cada prefixo (OpenAI account% vs GAIP account%), em vez de vir de save() ou uiContext.
Então… qual é a dificuldade em renomear a credencial? ![]()
Estou trabalhando com n8n há cerca de 4 anos, e percebi que deixar o nome base padrão leva a problemas ao atualizar credenciais depois ou ao determinar o que é o quê
não há dificuldade, mas é confuso
é normal @Jankaz , depois que você encontrar a sua forma de entender a questão vai ficar mais fácil. não algo configurável, elas são diferentes visualmente mesmo.
não encontrei nenhum parâmetro para alterar a lógica de geração automática de nomes
A separação por usuário/projeto existe no nível de permissão e visibilidade das credenciais, via RBAC/Projects, mas isso não significa que o contador automático de nomes também seja escopado por projeto. A documentação de RBAC fala sobre acesso a workflows e credenciais por projeto, não sobre algoritmo de nomeação.
como sugerido na thread, o contorno é nomear manualmente as credenciais com projeto/usuário no nome.