Autenticação e chaves de API
A API DUST autentica todos os pedidos /api/v1/* com um JWT bearer emitido pelo AuthD, o serviço de contas da DUST. As integrações de API atuam como uma Conta de serviço — uma identidade de máquina pertencente à sua organização — e nunca como uma pessoa. O fluxo é o seguinte:
- Um administrador da organização cria uma Conta de serviço e emite-lhe uma credencial (uma única vez).
- A sua integração troca a credencial por um token bearer de curta duração.
- Envie
Authorization: Bearer <token>nas chamadas à API e efetue uma nova troca quando o token expirar.
Contas de serviço
Seção intitulada “Contas de serviço”Uma Conta de serviço é uma identidade de máquina de pleno direito: pertence exatamente a uma organização, pode receber acesso a Equipas tal como um membro e todas as ações que realiza são registadas no livro de auditoria como sendo da Conta de serviço — não do funcionário que a configurou. As respetivas credenciais podem ser substituídas ou revogadas a qualquer momento sem afetar a conta pessoal de ninguém.
Estão disponíveis dois tipos de credenciais, e uma Conta de serviço pode ter ambos:
- Chave de API — a integração mais simples: troque a chave por um token com uma única chamada HTTP.
- Cliente OAuth2 (
client_credentials) — para middleware empresarial (SAP Integration Suite, MuleSoft, Boomi, …) com suporte integrado para OAuth2.
Criar uma chave de API
Seção intitulada “Criar uma chave de API”As Contas de serviço e as respetivas credenciais são geridas pelos administradores da organização no portal AuthD em authd.dustid.io.
- Inicie sessão em authd.dustid.io como administrador da organização.
- Abra a página da sua organização e selecione o separador Contas de serviço.
- Crie uma Conta de serviço (por exemplo, “Conector SAP” ou “Estação de digitalização da linha 3”).
- Abra Gerir na Conta de serviço e crie uma chave de API.
- Guarde a chave num gestor de segredos — trate-a como uma palavra-passe. É apresentada uma única vez.
Manter as credenciais no servidor
Seção intitulada “Manter as credenciais no servidor”Leia esta secção antes do primeiro exemplo: o local onde uma credencial reside é a decisão determinante para a segurança de uma integração DUST.
- As credenciais residem apenas nos seus servidores — em variáveis de ambiente ou num gestor de segredos, nunca em pacotes de cliente nem no controlo de código-fonte.
- Os tokens bearer também são credenciais. São de curta duração, mas um token emitido a partir da sua credencial atua com o acesso total da Conta de serviço — todas as organizações, Equipas e operações a que essa conta consegue aceder. Uma duração curta limita o período de exposição, não o alcance do impacto.
- Se a sua aplicação Web ou móvel precisar de dados da DUST, o padrão suportado é browser → o seu backend → API DUST. O seu backend conserva a credencial, emite o token bearer, decide que contexto e que operação são permitidos ao autor da chamada e chama diretamente a API DUST. O browser nunca recebe qualquer tipo de credencial DUST. As integrações de digitalização e móveis seguem exatamente este modelo: a captura é enviada para o seu backend, que chama os endpoints de Identificadores com credenciais mantidas no servidor.
- Uma Conta de serviço por aplicação e ambiente permite efetuar substituições, revogações e auditorias de forma precisa.
Trocar a chave por um token bearer
Seção intitulada “Trocar a chave por um token bearer”GET /api/auth/token recebe a chave de API no cabeçalho x-api-key e devolve um JWT. (O APID encaminha este pedido para o AuthD, pelo que um único URL de base abrange tudo.)
Esta chamada, bem como todas as chamadas baseadas no respetivo resultado, é executada num servidor.
curl -fsS "https://apid.dustid.io/api/auth/token" \ -H "x-api-key: $DUST_API_KEY"const response = await fetch("https://apid.dustid.io/api/auth/token", { headers: { "x-api-key": process.env.DUST_API_KEY! },});const { token, expiresIn } = await response.json();Resposta:
{ "token": "eyJhbGciOi...", "expiresIn": 900, "expiresAt": "2026-07-14T22:40:00.000Z" }expiresIn é o tempo de vida restante do token, em segundos; expiresAt representa o mesmo momento como timestamp ISO 8601. Ambos são derivados da claim de expiração do próprio token, pelo que um token emitido sem essa claim é devolvido apenas como { "token": "…" } — leia estes valores de forma defensiva e, caso não estejam presentes, utilize a sua própria margem conservadora. Utilize qualquer um deles para agendar a troca seguinte; não codifique uma duração fixa.
OAuth2 client_credentials
Seção intitulada “OAuth2 client_credentials”Para plataformas com suporte nativo para OAuth2, crie um cliente OAuth na Conta de serviço em vez de uma chave de API, ou em conjunto com esta. O ID e o segredo do cliente são apresentados uma única vez durante a criação.
Peça um token ao endpoint de tokens da Conta de serviço através da concessão client_credentials padrão — são aceites tanto client_secret_post (campos de formulário) como client_secret_basic (HTTP Basic):
curl -fsS "https://authd.dustid.io/api/auth/dust/service-accounts/token" \ -d grant_type=client_credentials \ -d client_id="$DUST_CLIENT_ID" \ -d client_secret="$DUST_CLIENT_SECRET"Resposta (resposta de token OAuth2 padrão):
{ "access_token": "eyJhbGciOi...", "token_type": "Bearer", "expires_in": 900 }O token resultante tem exatamente a mesma estrutura e os mesmos direitos que um token obtido através da troca de uma chave de API — utilize-o da mesma forma. Se o seu middleware pedir um “URL do token”, utilize o endpoint acima.
Utilizar o token bearer
Seção intitulada “Utilizar o token bearer”Envie o token em todas as chamadas à API principal:
Authorization: Bearer <token>Uma forma rápida de confirmar que o token funciona:
curl -fsS "https://apid.dustid.io/api/v1/me" \ -H "Authorization: Bearer $DUST_TOKEN"Os pedidos sem um token válido recebem 401 com o corpo { "code": "UNAUTHORIZED", "message": "...", "status": 401 } — consulte Convenções dos pedidos para conhecer o contrato de erros e Erros e resultados das digitalizações para ver a lista completa de códigos.
Expiração e renovação dos tokens
Seção intitulada “Expiração e renovação dos tokens”Os tokens bearer das Contas de serviço são de curta duração — atualmente, 15 minutos — mas deve sempre ler a duração na resposta (expiresIn/expiresAt na troca da chave, expires_in na concessão OAuth), em vez de a codificar. Não existe um refresh token: quando um token expirar, volte a trocar a credencial.
Um cliente robusto combina ambos os padrões — renova de forma proativa com uma margem de segurança e trata uma ocorrência de 401 como um sinal para renovar e repetir o pedido (isto também abrange desvios do relógio e revogações durante o período de validade):
let cached: { token: string; refreshAfter: number } | null = null;
async function getToken(): Promise<string> { if (cached && Date.now() < cached.refreshAfter) return cached.token; const res = await fetch("https://apid.dustid.io/api/auth/token", { headers: { "x-api-key": process.env.DUST_API_KEY! }, }); if (!res.ok) throw new Error(`token exchange failed: ${res.status}`); const { token, expiresIn } = await res.json(); // refresh 60s before expiry, never cache a token for less than 5s cached = { token, refreshAfter: Date.now() + Math.max(expiresIn - 60, 5) * 1000 }; return token;}
async function apiFetch(url: string, init: RequestInit = {}): Promise<Response> { const call = async () => { // new Headers() handles every HeadersInit shape (plain object, Headers, // tuple array) — an object spread would silently drop the latter two. const headers = new Headers(init.headers); headers.set("Authorization", `Bearer ${await getToken()}`); return fetch(url, { ...init, headers }); }; let res = await call(); if (res.status === 401) { cached = null; // token revoked or expired early — refresh once and retry res = await call(); } return res;}A troca tem um custo reduzido; não crie caches prolongadas em torno desta operação. A curta duração também simplifica a resposta a incidentes: a revogação de uma credencial impede imediatamente a emissão de novos tokens, e qualquer token já emitido expira ao fim de poucos minutos.
Atribuição do autor declarado
Seção intitulada “Atribuição do autor declarado”Uma Conta de serviço autentica o sistema; não permite à DUST saber que pessoa premiu o botão no seu ERP ou nas suas instalações de produção. Se pretender essa rastreabilidade, declare-a em cada pedido através do cabeçalho Dust-Ctx-Declared-Actor — um pequeno objeto JSON:
Dust-Ctx-Declared-Actor: {"id": "JDOE", "system": "SAP", "displayName": "Jane Doe"}idé obrigatório;system,displayNameerolesão opcionais. O valor pode ser codificado como URI (obrigatório se contiver caracteres não ASCII) e não pode exceder 1 KB.- O autor declarado é registado textualmente em todos os eventos escritos pelo pedido e apresentado no histórico de atividades como atribuição declarada — é fornecido pela sua integração, não é verificado pela DUST e nunca concede nem restringe permissões.
- Um administrador da organização pode definir a política de atribuição de uma Conta de serviço como obrigatória; nesse caso, os pedidos de escrita sem um autor declarado são rejeitados com
403 ATTRIBUTION_REQUIRED.
Como os tokens são verificados
Seção intitulada “Como os tokens são verificados”A API verifica a assinatura de cada token bearer através do JSON Web Key Set do AuthD e verifica as claims de emissor (https://authd.dustid.io/api/auth em produção) e de audiência. Normalmente, não precisa de conhecer este detalhe — mas, se o seu próprio backend precisar de verificar JWTs emitidos pela DUST (por exemplo, para confiar num token encaminhado por outro serviço interno), o JWKS é público:
GET https://apid.dustid.io/api/auth/jwksDevolve um documento padrão { "keys": [ ... ] }, utilizável com qualquer biblioteca JOSE.
Uma integração de digitalização no browser, do início ao fim
Seção intitulada “Uma integração de digitalização no browser, do início ao fim”O padrão abaixo é o que todas as integrações de digitalização em browsers ou dispositivos móveis devem seguir. Dois ficheiros, dois locais de execução, uma credencial — que nunca sai do segundo ficheiro.
// No DUST credential appears in this file, and none should.async function identify(capture: Blob) { const form = new FormData(); form.set("capture", capture); // Your own endpoint, authenticated with your own session. const response = await fetch("/api/identify", { method: "POST", body: form, credentials: "same-origin" }); return await response.json();}// Holds the DUST credential, mints the bearer token, chooses the context,// and applies your own authorization before calling DUST.export async function handleIdentify(request: Request, session: YourSession) { if (!session.mayScan) return new Response("Forbidden", { status: 403 });
const capture = (await request.formData()).get("capture") as Blob; const form = new FormData(); form.set("tagType", "DUST"); form.set("data", capture); form.set("searchTeamIds", JSON.stringify(session.allowedTeamIds));
return await fetch("https://apid.dustid.io/api/v1/tags/identify", { method: "POST", headers: { Authorization: `Bearer ${await getToken()}`, // server-held credential "Dust-Ctx-Org-Id": session.organizationId, // your choice, not the caller's }, body: form, });}O seu proxy também é o local natural para aplicar regras por utilizador que a API DUST não pode conhecer: em que Equipas este funcionário pode pesquisar, se pode vincular além de identificar e que informações são registadas.
Substituir uma chave
Seção intitulada “Substituir uma chave”Uma Conta de serviço pode ter várias credenciais ativas em simultâneo, pelo que a substituição não requer qualquer interrupção:
- Crie uma chave de substituição (ou um cliente OAuth) na mesma Conta de serviço.
- Implemente-a na sua aplicação (ambas as credenciais funcionam durante o período de sobreposição).
- Confirme que o tráfego de produção utiliza a nova credencial — a hora da última utilização de cada chave está visível no portal.
- Revogue a credencial antiga.
Próximos passos
Seção intitulada “Próximos passos”- Início rápido da API — do token ao primeiro Registo em cinco minutos.
- Convenções dos pedidos — os cabeçalhos de contexto necessários para todas as chamadas no âmbito da organização.
- Erros e resultados das digitalizações — tratamento de
401, renovação única perante um 401 e o restante contrato de falhas. - Referência completa da API — todos os endpoints e esquemas.