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

# Integrações de parceiros do Outposts

> Conecte um outpost de uma plataforma parceira com uma troca de código PKCE

<Note>
  Notas preliminares — este fluxo está em estágio inicial de desenvolvimento, e os detalhes abaixo podem
  mudar.
</Note>

Plataformas parceiras (por exemplo, provedores de computação) podem conectar um outpost em nome de um cliente. O admin do Devin do cliente autoriza a conexão no navegador; Devin então cria um outpost e um usuário de serviço e entrega ao parceiro um token para executar workers no outpost.

O fluxo é uma troca de código de autorização em estilo OAuth simplificado com [PKCE](https://datatracker.ietf.org/doc/html/rfc7636). O navegador transporta apenas um **código** de curta duração e de uso único — o token do usuário de serviço é trocado entre servidores e nunca passa pelo navegador.

<div id="prerequisites">
  ## Pré-requisitos
</div>

* **Lista de permissões de callback.** Todo `callback_url` que você usar deve estar na lista de permissões do Devin para sua integração. Isso é configurado pela Cognition — envie as URLs exatas com antecedência. Uma URL que não estiver na lista será rejeitada.
* **Outposts ativado.** A conta do cliente deve estar com o Outposts ativado.
* **Autorização de admin.** Para autorizar uma conexão, é necessário um admin do Devin com permissões de enterprise-settings e de gerenciamento de usuários de serviço. O parceiro nunca precisa de um token do Devin — o admin faz a autorização na própria sessão do navegador.

<div id="flow-overview">
  ## Visão geral do fluxo
</div>

```
Partner backend                 Admin's browser                 Devin
     │                                │                            │
     │ 1. gen code_verifier,          │                            │
     │    derive code_challenge       │                            │
     │ 2. redirect to app.devin.ai/outposts/connect?…code_challenge│
     │───────────────────────────────>                            │
     │                                │ 3. admin confirms, "Connect"│
     │                                │──────confirmar conexão───────>
     │                                │ 4. redirect callback_url?code=…  │
     │<───────────────────────────────                            │
     │ 5. POST /outposts/connection-token  (code + code_verifier) │
     │────────────────────────────────────────────────────────────>
     │ 6. { access_token, api_base_url, … }                       │
     │<────────────────────────────────────────────────────────────
     │ 7. run outpost workers with access_token                   │
```

<div id="1-generate-a-pkce-verifier-and-challenge">
  ### 1. Gere um verificador e um desafio PKCE
</div>

No seu backend, para cada tentativa de conexão:

* Gere um **`code_verifier`** aleatório e com alta entropia: 43–128 caracteres do alfabeto não reservado `[A-Za-z0-9-._~]` (por exemplo, `base64url(random 32 bytes)` com o padding removido).
* Derive o **`code_challenge`** como o base64url sem padding do SHA-256 do verificador (PKCE "S256"):

```python theme={null}
import base64, hashlib, secrets

code_verifier = secrets.token_urlsafe(32)  # 43+ caracteres, alfabeto não reservado
code_challenge = (
    base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode()).digest())
    .rstrip(b"=")
    .decode()
)
```

Armazene o `code_verifier` no servidor (vinculado ao estado que você usar para correlacionar o callback posterior). Nunca envie o verificador para o navegador — apenas o desafio sai do seu backend.

<div id="2-redirect-the-admin-to-the-connect-page">
  ### 2. Redirecione o admin para a página de conexão
</div>

Envie o admin do cliente para a página de conexão do Devin com o desafio e o callback:

```
https://app.devin.ai/outposts/connect
  ?callback_url=https://partner.example.com/devin/outpost-callback
  &outpost_name=my-outpost
  &outpost_image=https://partner.example.com/logo.png
  &platform=linux
  &code_challenge=<code_challenge>
```

| Parâmetro        | Obrigatório | Observações                                                                                   |
| ---------------- | ----------- | --------------------------------------------------------------------------------------------- |
| `callback_url`   | sim         | Para onde Devin envia o código de uso único. Deve estar na sua lista de permissões.           |
| `code_challenge` | sim         | O desafio PKCE S256 da etapa 1.                                                               |
| `outpost_name`   | não         | Nome sugerido do outpost. O admin pode editá-lo antes de confirmar.                           |
| `outpost_image`  | não         | URL de um ícone PNG usado para representar o outpost, como o logotipo da sua empresa.         |
| `platform`       | não         | Plataforma do outpost pré-selecionada: `macos`, `linux` ou `windows`. O admin pode alterá-la. |

Se o admin não tiver iniciado sessão, a página de conexão guarda esses parâmetros e solicita que ele faça login primeiro; depois, retoma o processo.

<div id="3-admin-confirms">
  ### 3. O admin confirma
</div>

A página de conexão exibe uma confirmação com um nome de outpost editável e a plataforma (e seu `outpost_image`, se fornecido). Quando o admin clica em **Connect**, Devin valida as permissões, a lista de permissões de callback e se o nome do outpost está disponível; depois, armazena um código criptografado de uso único (TTL de 10 minutos) e redireciona de volta para seu app com o código de uso único.

Ainda não existe outpost nem usuário de serviço — eles são criados apenas quando o código é resgatado (etapa 5). Um código que não for resgatado simplesmente expira.

<div id="4-devin-redirects-the-code-to-your-callback">
  ### 4. Devin redireciona o código para seu callback
</div>

O navegador é redirecionado para seu `callback_url`, com o código anexado:

```
https://partner.example.com/devin/outpost-callback?code=<one-time code>
```

<div id="5-exchange-the-code-server-to-server">
  ### 5. Faça a troca do código entre servidores
</div>

No seu backend, recupere o `code_verifier` que você armazenou na etapa 1 e troque o código no endpoint de token. Esta é uma requisição de token no estilo OAuth, codificada como formulário:

```bash theme={null}
curl -X POST "https://api.devin.ai/outposts/connection-token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=authorization_code" \
  --data-urlencode "code=<one-time code>" \
  --data-urlencode "code_verifier=<code_verifier>"
```

Este endpoint não requer autenticação do Devin — a posse do código junto com o verificador PKCE correspondente é a prova. Ele não é autenticado de propósito: o código é de uso único (consumido atomicamente), tem curta duração e está vinculado ao seu desafio.

<div id="6-receive-the-credentials">
  ### 6. Receba as credenciais
</div>

Se a operação for bem-sucedida, Devin cria o outpost e um usuário de serviço com escopo para executar o worker do outpost e retorna:

```json theme={null}
{
  "outpost_id": "...",
  "account_id": "...",
  "outpost_name": "my-outpost",
  "service_user_id": "...",
  "api_base_url": "https://api.devin.ai",
  "access_token": "cog_...",
  "token_type": "bearer"
}
```

As respostas incluem `Cache-Control: no-store` — não as armazene em cache.

<div id="7-run-outpost-workers">
  ### 7. Executar os workers do outpost
</div>

Armazene `access_token` e `api_base_url` com segurança e use o token como credencial Bearer para executar os workers do outpost no outpost.

<div id="error-handling">
  ## Tratamento de erros
</div>

O endpoint de token segue a [RFC 6749 §5.2](https://datatracker.ietf.org/doc/html/rfc6749#section-5.2). Um código desconhecido, expirado, já utilizado (reutilizado) ou com PKCE incompatível retorna `400`:

```json theme={null}
{
  "error": "invalid_grant",
  "error_description": "Invalid or expired connection code"
}
```

Como os códigos são de uso único e expiram após 10 minutos, considere qualquer `invalid_grant` como um erro fatal: descarte o `code_verifier` armazenado e reinicie o fluxo a partir da etapa 1.

<div id="security-notes">
  ## Notas de segurança
</div>

* **O token nunca passa pelo navegador.** Apenas o código de uso único é encaminhado por redirecionamento; o token do usuário de serviço é retornado exclusivamente na troca entre servidores.
* **O PKCE vincula o código a você.** O código é inútil sem o `code_verifier`, mantido apenas no seu backend, então interceptar o redirecionamento (ou o código) não basta para resgatá-lo.
* **Os códigos são de uso único e têm curta duração.** O resgate consome o código atomicamente; além disso, ele expira após 10 minutos.
* **As URLs de callback estão na lista de permissões.** O Devin só encaminha um código para uma `callback_url` que a Cognition pré-aprovou para a sua integração.
* **Verifique se o código é do usuário que fez a requisição.** Confirme que o código retornado ao seu callback pertence ao mesmo usuário que solicitou originalmente a conexão. Isso impede que um invasor engane um usuário e vincule o Devin, sem que ele perceba, a um sandbox controlado pelo invasor.
* **Use um `outpost_name` adequado.** O admin pode fazer override; o nome que você informa é apenas uma sugestão.
