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

# Ambientes

> Live e test: mesmo schema, nunca as mesmas linhas, e quem chama não escolhe.

Toda organização tem exatamente dois ambientes, **live** e **test**, criados junto
com ela. Não dá para criar nem deletar, e nunca existe um terceiro.

As tabelas do plano de clientes carregam `environment_id` ao lado de
`organization_id`. Dados de teste e dados de produção são o mesmo schema e nunca as
mesmas linhas.

```bash theme={null}
curl -s $API/v1/organization/environments \
  -H "Authorization: Bearer $UK_SESSION" \
  -H "X-Organization-Id: org_4b1e…"
```

```json theme={null}
{
  "environments": [
    { "id": "…", "kind": "live", "auth_mode": "hosted", "created_at": "…" },
    { "id": "…", "kind": "test", "auth_mode": "hosted", "created_at": "…" }
  ]
}
```

## A credencial decide

É a regra em torno da qual o desenho inteiro gira.

Na superfície de máquina, o ambiente é resolvido **a partir da linha da chave
armazenada, em toda requisição**. Não de um header, não de um parâmetro de query,
não de um campo no corpo. Não existe como nomear um.

```
uk_sk_live_…  →  live      uk_pk_live_…  →  live
uk_sk_test_…  →  test      uk_pk_test_…  →  test
```

O que significa:

* um id de live buscado com uma chave de test responde `404` — e o 404 não revela
  que a linha existe em outro lugar;
* um contato identificado com uma chave de test é inalcançável a partir de live;
* apontar staging para produção não é um erro que se cometa num arquivo de
  config, porque não há campo para errar.

O tipo de ambiente é gravado no prefixo da chave, então uma chave que vaza diz na
própria cara qual modo ela abre.

<Note>
  `GET /v1/me` é a forma mais barata de confirmar qual ambiente uma chave abre. Toda
  integração deveria chamá-lo uma vez no start-up.
</Note>

## O painel é a exceção

Staff é autorizado na organização inteira, então as leituras do painel recebem o
ambiente como parâmetro explícito de **visão**:

```bash theme={null}
curl -s "$API/v1/organization/contacts?environment=test" \
  -H "Authorization: Bearer $UK_SESSION" \
  -H "X-Organization-Id: org_4b1e…"
```

O padrão é `live`. Qualquer coisa fora de `live` ou `test` responde
`400 invalid_request`.

Essa é a postura oposta à da superfície de máquina, e segura exatamente por isso:
quem chama já está autorizado nos dois ambientes, então deixar escolher não amplia
alcance nenhum. Uma credencial de máquina não ganha esse parâmetro, jamais.

Na interface do painel o ambiente ativo é uma preferência de visão no cliente,
marcada pelo seletor no header e por uma faixa âmbar sempre que o modo de teste
está ligado.

## O modo de auth é por ambiente

Cada ambiente carrega seu próprio `auth_mode`, `hosted` ou `federated`. Isso é
deliberado: dá para avaliar hosted em test enquanto produção segue federada.

```bash theme={null}
curl -s -X PATCH $API/v1/organization/environments/{id} \
  -H "Authorization: Bearer $UK_SESSION" \
  -H "X-Organization-Id: org_4b1e…" \
  -H 'Content-Type: application/json' \
  -d '{ "auth_mode": "federated" }'
```

Exige `organization:update`. Os endpoints do outro modo recusam em vez de virarem
um segundo login em silêncio:

| Chamado contra                                   | Resposta                        |
| ------------------------------------------------ | ------------------------------- |
| `/v1/boot` com `external_id`, em ambiente hosted | `409 environment_not_federated` |
| `/v1/contact-auth/signup` em ambiente federado   | `409 environment_not_hosted`    |

Veja [Escolhendo o modo de auth](/pt-br/customer-auth/modes).

## O segredo de identidade

Um ambiente federado também guarda um **segredo de identidade** — a chave HMAC com
que o seu servidor assina valores de `external_id`. É por ambiente, criado na
primeira leitura, e lê-lo exige `api_keys:write`: esse segredo emite sessões
*verificadas*, então lê-lo é possuí-lo.

```bash theme={null}
curl -s $API/v1/organization/environments/{id}/identity \
  -H "Authorization: Bearer $UK_SESSION" \
  -H "X-Organization-Id: org_4b1e…"
```

Rotacionar o substitui e mantém o anterior verificando por uma **janela de carência
de 24 horas** — tempo suficiente para uma frota redeployar, curto o bastante para
que um segredo antigo roubado tenha prazo.

```bash theme={null}
curl -s -X POST $API/v1/organization/environments/{id}/identity/rotate \
  -H "Authorization: Bearer $UK_SESSION" \
  -H "X-Organization-Id: org_4b1e…"
```

Os dois endpoints respondem `501 federated_identity_unavailable` quando o servidor
não pode guardar o segredo cifrado com segurança.
