Pular para o conteúdo principal

Endpoints de API keys, service accounts e jobs

Gestão programática de credenciais e leitura de jobs assíncronos de longa duração.

Tabela de endpoints

API keys

MétodoCaminhoPermissão
POST/platform/organizations/{organization_id}/api-keysmember:manage
GET/platform/organizations/{organization_id}/api-keysSessão
GET/platform/organizations/{organization_id}/api-keys/{key_id}Sessão
PATCH/platform/organizations/{organization_id}/api-keys/{key_id}member:manage
POST/platform/organizations/{organization_id}/api-keys/{key_id}/revokemember:manage
POST/platform/organizations/{organization_id}/api-keys/{key_id}/rotatemember:manage
GET/platform/organizations/{organization_id}/api-keys/{key_id}/usageSessão

Service accounts

MétodoCaminhoPermissão
POST/platform/organizations/{organization_id}/service-accountsmember:manage
GET/platform/organizations/{organization_id}/service-accountsSessão
GET/platform/organizations/{organization_id}/service-accounts/{sa_id}Sessão
PATCH/platform/organizations/{organization_id}/service-accounts/{sa_id}member:manage

Jobs assíncronos

MétodoCaminhoPermissão
GET/platform/organizations/{organization_id}/jobsSessão
GET/platform/organizations/{organization_id}/jobs/{job_id}Sessão

API keys

POST /.../api-keys

Cria uma nova chave. O valor completo (raw_key) aparece apenas uma vez nesta resposta — guarde imediatamente.

Request body (ApiKeyCreateRequest):

{
"name": "CI pipeline",
"description": "Deploy pipeline do SOC",
"scopes": ["analysis:run", "projects:read", "cases:write"],
"expires_in_days": 365,
"project_id": "prj_01H…"
}
  • scopes[] — valores aceitos (veja Autenticação): projects:read, projects:write, rulesets:read, rulesets:write, analysis:run, cases:read, cases:write, reviews:read, reviews:write, versions:read, versions:write, admin:*. Escopos desconhecidos → 422.
  • expires_in_days — 1 a 3650 (10 anos). null para sem expiração.
  • project_id — opcional; se preenchido, a chave só funciona no projeto informado.

Response 201 (ApiKeyCreatedResponse):

{
"key": {
"id": "key_01H…",
"name": "CI pipeline",
"description": "Deploy pipeline do SOC",
"organization_id": "org_01H…",
"project_id": "prj_01H…",
"scopes": ["analysis:run", "projects:read", "cases:write"],
"key_prefix": "rfk_01H2XA9C",
"is_active": true,
"last_used_at": null,
"expires_at": "2027-04-24T00:00:00Z",
"created_by": "usr_01H…",
"created_at": "2026-04-24T15:30:00Z",
"updated_at": "2026-04-24T15:30:00Z"
},
"raw_key": "rfk_01H2XA9CKEB7WZG8RMN2KPQV7_e6c4f2abcd…"
}

Emite webhook: api_key.created.

GET /.../api-keys

Lista chaves da organização.

Response 200: array de ApiKeyRecord (sem raw_key).

GET /.../api-keys/{key_id}

Busca uma chave específica.

PATCH /.../api-keys/{key_id}

Atualização parcial (name, description, scopes). Não permite re-gerar o valor — use rotate para isso.

POST /.../api-keys/{key_id}/revoke

Revoga a chave imediatamente. Irreversível.

Request body (ApiKeyRevokeRequest):

{ "reason": "Rotacionada manualmente após vazamento" }

Response 200: ApiKeyRecord com is_active=false. Emite webhook api_key.revoked.

POST /.../api-keys/{key_id}/rotate

Gera novo segredo mantendo o id e os escopos. O valor antigo deixa de ser aceito imediatamente.

Response 200: ApiKeyCreatedResponse (com raw_key novo — guarde!).

GET /.../api-keys/{key_id}/usage

Histórico de uso da chave (últimas N chamadas). Útil para auditar onde a chave está sendo usada.

Response 200: array de ApiKeyUsageRecord:

[
{
"id": "usage_...",
"key_id": "key_01H…",
"endpoint": "/api/v1/analysis/validate",
"method": "POST",
"status_code": 200,
"duration_ms": 142.7,
"request_id": "…",
"ip_address": "203.0.113.10",
"user_agent": "curl/8.4",
"created_at": "2026-04-24T14:00:00Z"
}
]

Service accounts

Service account = identidade de um sistema (não um humano) com papel dentro da organização. Usada como "proprietário" de recursos criados por integrações automatizadas — auditoria fica clara.

POST /.../service-accounts

{
"name": "Bot CI",
"description": "Robô que publica versões a partir do Git",
"role": "engineer"
}

Response 201: ServiceAccountRecord com slug e role.

GET /.../service-accounts

Lista contas de serviço.

PATCH /.../service-accounts/{sa_id}

Atualiza name, description, role ou is_active.

Jobs assíncronos

Tarefas longas (batch logtest, sync Git, pipeline poll, rotação de secrets) são enfileiradas como jobs e executadas em background. O cliente consulta o estado via os endpoints abaixo.

GET /.../jobs

Lista jobs da organização.

Response 200: array de JobRecord:

[
{
"id": "job_...",
"organization_id": "org_...",
"project_id": "prj_...",
"type": "batch_regression",
"status": "running",
"progress": 12,
"total": 50,
"created_by": "usr_...",
"started_at": "2026-04-24T15:00:00Z",
"completed_at": null,
"error_message": null,
"created_at": "2026-04-24T14:59:58Z",
"updated_at": "2026-04-24T15:01:12Z"
}
]

typeimport_export.

statuscancelled.

GET /.../jobs/{job_id}

Retorna JobResultRecord, que é o JobRecord + campo result (dicionário com o output da tarefa quando completed).

Polling recomendado:

import time, httpx

def wait_for_job(client, org_id, job_id, timeout=600):
deadline = time.time() + timeout
while time.time() < deadline:
r = client.get(f"{base}/platform/organizations/{org_id}/jobs/{job_id}")
r.raise_for_status()
job = r.json()
if job["status"] in ("completed", "failed", "cancelled"):
return job
time.sleep(2)
raise TimeoutError("Job demorou demais")

Estruturas compartilhadas

ApiKeyRecord

{
"id": "string",
"name": "string",
"description": "string",
"organization_id": "string",
"project_id": "string|null",
"scopes": ["string"],
"key_prefix": "rfk_XXXXXXXX",
"is_active": true,
"last_used_at": "ISO 8601|null",
"expires_at": "ISO 8601|null",
"created_by": "string|null",
"created_at": "ISO 8601",
"updated_at": "ISO 8601"
}

key_prefix são os 12 primeiros chars do raw_key. Nunca exposto o segredo completo fora do momento da criação/rotação.

ApiKeyUsageRecord

{
"id": "string",
"key_id": "string",
"endpoint": "string",
"method": "string",
"status_code": 200,
"duration_ms": 123.4,
"request_id": "string|null",
"ip_address": "string|null",
"user_agent": "string|null",
"created_at": "ISO 8601"
}

JobRecord

Ver acima. JobResultRecord = JobRecord + result: object.