@neetru/cli 2.28.8 → 2.28.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/README.md +2 -1
- package/dist/commands/admin/oidc-login.d.ts +18 -0
- package/dist/commands/admin/oidc-login.js +62 -0
- package/dist/commands/admin/oidc-login.js.map +1 -1
- package/dist/commands/agent-release.d.ts +2 -0
- package/dist/commands/agent-release.js +27 -2
- package/dist/commands/agent-release.js.map +1 -1
- package/dist/commands/agent-write.d.ts +1 -0
- package/dist/commands/agent-write.js +4 -0
- package/dist/commands/agent-write.js.map +1 -1
- package/dist/commands/deploy.d.ts +15 -0
- package/dist/commands/deploy.js +29 -0
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/doctor.js +12 -6
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/ops.d.ts +17 -0
- package/dist/commands/ops.js +50 -18
- package/dist/commands/ops.js.map +1 -1
- package/dist/commands/products-db.d.ts +1 -0
- package/dist/commands/products-db.js +15 -15
- package/dist/commands/products-db.js.map +1 -1
- package/dist/commands/servers.d.ts +2 -3
- package/dist/commands/servers.js +4 -7
- package/dist/commands/servers.js.map +1 -1
- package/dist/commands/vm.d.ts +2 -0
- package/dist/commands/vm.js +8 -0
- package/dist/commands/vm.js.map +1 -1
- package/dist/index.js +52 -6
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-artifact-url.d.ts +19 -0
- package/dist/lib/agent-artifact-url.js +48 -0
- package/dist/lib/agent-artifact-url.js.map +1 -0
- package/dist/lib/api-client.d.ts +11 -3
- package/dist/lib/api-client.js +55 -24
- package/dist/lib/api-client.js.map +1 -1
- package/dist/lib/api-error.js +32 -1
- package/dist/lib/api-error.js.map +1 -1
- package/dist/lib/auth.d.ts +2 -9
- package/dist/lib/auth.js +34 -18
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/cli-write.d.ts +31 -0
- package/dist/lib/cli-write.js +51 -2
- package/dist/lib/cli-write.js.map +1 -1
- package/dist/lib/telemetry.d.ts +7 -0
- package/dist/lib/telemetry.js +9 -0
- package/dist/lib/telemetry.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -46,6 +46,40 @@ Convenção: [Keep a Changelog](https://keepachangelog.com/) + [SemVer](https://
|
|
|
46
46
|
- **`vm-memory.test.ts`** (novo, 18 casos): status GET+JSON+tabela; set GET→POST com body correto + header MFA; alias `--max`; herança de teto com só `--max-old-space`; `--high`/`--confirm-shrink`/`--reason` no body; validações fail-fast (slug inválido, sem flags, `max-old-space ≥ memory-max`, `high > memory-max`, abaixo do piso, não-inteiro, slug sem teto); avisos de overcommit / encolhimento / RAM desconhecida (o Core continua sendo a autoridade fail-closed).
|
|
47
47
|
- **`db-move.test.ts`** (novo) — mocka o Core (`apiRequest`) e as deps de escrita. Cobre: (a) **sucesso** (só reporta "concluída" quando o poll chega em `done`; body/headers/MFA corretos no POST); (b) **falha com rollback** (`rolled_back` + `lastError` → "seguiu na origem" + `setSafeExitCode(1)`, sem afirmar sucesso); (c) **`--yes`** (repassa `yes:true` ao `confirmDestructive` e prossegue); (d) **`--dry-run`** (sem confirmação/MFA, `body.dryRun=true`, sem poll); (e) manual-cutover (pausa e instrui `db move confirm`); (f) guardrails de input (`--to` ausente, estratégia inválida, produto ambíguo → exit 1 sem tocar o Core); (g) `confirm`/`abort`/`status`/`where`; e os helpers PUROS (`classifyRelocation`, `validateMaxQuiesceMs`, `formatVerifyReportLines`).
|
|
48
48
|
|
|
49
|
+
## [2.28.10] — 2026-09-29 (segurança: step-up MFA nas rotas endurecidas pela auditoria cli/v1 do Core)
|
|
50
|
+
|
|
51
|
+
> **Publicar ANTES do deploy do Core** com a auditoria cli/v1 2026-09-29 (branch `fix/cli-v1-auditoria-2026-09-29` do `neetru-core`). Sem este CLI, os comandos abaixo passam a bater `401 mfa_required` sempre. Contra o Core atual os headers MFA são ignorados (compatível).
|
|
52
|
+
|
|
53
|
+
### Segurança / Corrigido
|
|
54
|
+
|
|
55
|
+
- **`neetru agent release`** — o Core exige step-up MFA em **todos** os canais (H1: publicar release atinge a frota inteira via auto-update). Novo `--mfa-token <code>`; segue o `resolveStepUp` padrão (sessão de 1h → `--mfa-token` → prompt TOTP; fail-closed sem TTY). A URL de cada binário agora é **validada localmente** com a mesma regra do Core (`src/lib/agent-artifact-url.ts`): só `https://core.neetru.com/releases/...` ou o bucket GCS de releases (`neetru-agent-releases`, ou `NEETRU_AGENT_RELEASES_BUCKET`) — sem porta, sem credencial embutida. Fora disso: erro claro com as origens aceitas, **antes** de pedir MFA ou chamar a API. `--dry-run` segue sem MFA.
|
|
56
|
+
- **`neetru ops reg-token`** — step-up MFA obrigatório (H5) + `--mfa-token`.
|
|
57
|
+
- **`neetru ops bootstrap-admin`** — com admin existente o Core exige step-up MFA (H2). Como o CLI não sabe se já há admin, manda a sessão de 1h / `--mfa-token` se houver e, no `401 mfa_required`, prompta o TOTP e repete uma vez (em `--json`/não-TTY: fail-closed com `error: "mfa_required"`). Novo **`--reactivate`** (envia `reactivate: true`) para reativar staff desligado — sem ele o Core recusa com 409 `staff_disabled`.
|
|
58
|
+
- **`neetru ops migrate cli-keys`** — step-up MFA fora do `--dry-run` (M4) + `--mfa-token`. Dry-run segue sem MFA.
|
|
59
|
+
- **`neetru vm provision`** — step-up MFA obrigatório (M6: cada chamada cria uma VM faturada), resolvido depois da confirmação de custo + `--mfa-token`.
|
|
60
|
+
- **`neetru deploy --env prod|production`** — step-up MFA (M7, mesmo gate de `promote`) nos três alvos (vm, workspace, cloud-run), resolvido **logo antes** do `POST /api/cli/v1/deploy` (depois do build/upload, pra o TOTP não vencer no meio). Novo `--mfa-token`. `dev`/`staging` inalterados. Com `--non-interactive`/`--json` nunca prompta (fail-closed com instrução).
|
|
61
|
+
- **Mensagem do 401** — `handleApiError` distingue `401 mfa_required` ("Step-up MFA exigido: … passe --mfa-token ou rode `neetru auth mfa-session`"; `--json`: `error: "mfa_required"`) de token inválido, e mostra a `message`/`error_description` que o `requireCliAuth` do Core passou a mandar (M8). O 401 legado (`{error:"Unauthorized"}`) mantém o fallback "Execute: neetru login". Exit code segue 2. O parser do `apiRequest` passa a preferir `code` explícito ao `error` string (RFC) quando os dois vêm juntos.
|
|
62
|
+
- Não há comando `functions move|redeploy|revert` no CLI — o gate de MFA (M5) dessas rotas não tem superfície aqui.
|
|
63
|
+
|
|
64
|
+
Revisão adversarial do Core (`neetru-core` PR #512):
|
|
65
|
+
|
|
66
|
+
- **`neetru agent canary start`** — step-up MFA (start empurra a versão pra parte da frota, mesmo peso do rollback) + `--mfa-token`.
|
|
67
|
+
- **`neetru servers provision`** — MFA em **toda** provisão (M6; antes só com `--is-db-vm`).
|
|
68
|
+
- **`neetru admin database set-status`** — o Core exige MFA quando o banco está `active`/`degraded` (H3). Como o CLI não sabe o estado, usa `withStepUpRetry` (tenta; no `401 mfa_required` pede o TOTP e repete 1x) + `--mfa-token`. `archived` passou a ser recusado pelo Core nessa rota (use `db delete`).
|
|
69
|
+
- **Novo `neetru admin oidc-login rotate <clientId> --product-id <id> [--immediate]`** — `POST /api/cli/v1/products/{id}/oidc-login/rotate` com step-up MFA. Mesmo contrato do `create`: o Core **não devolve o secret** (vai pro Secret Manager e o próximo deploy o injeta server-side); a saída mostra `previousSecretValidUntil` (graça de 24h) ou, com `--immediate` (`{immediate:true}`), avisa que o secret anterior já não vale e o login cai até o próximo deploy.
|
|
70
|
+
- **`neetru ops bootstrap-admin`** sem admin existente — envia `x-bootstrap-secret` a partir de `--bootstrap-secret <valor>` ou env `NEETRU_BOOTSTRAP_SECRET` (nunca logado/impresso); com o segredo, a sessão CLI é opcional.
|
|
71
|
+
|
|
72
|
+
### Interno
|
|
73
|
+
|
|
74
|
+
- `cli-write`: `withStepUpRetry` (step-up condicional com retry único no `401 mfa_required`), `isMfaRequiredError`; `StepUpOptions` ganha `nonInteractive` e `skipSession`.
|
|
75
|
+
|
|
76
|
+
### Testes
|
|
77
|
+
|
|
78
|
+
- **`step-up-mfa-auditoria-cli-v1.test.ts`** (novo, `cli-write` real + `homedir` temporário): allowlist da URL (aceita/recusa, env do bucket); `agent release` (URL ruim → exit 1 sem MFA/API; header token/sessão; fail-closed; dry-run); `reg-token`; `bootstrap-admin` (sem 401 → 1 chamada; `--reactivate` no body; retry com prompt TOTP; sessão recusada → retry ignora a sessão; `--json` fail-closed; TOTP recusado não repete → exit 2); `migrate cli-keys` (dry-run sem header; aplicar com header; fail-closed); `vm provision`; `deploy` (`isProdEnv`, staging sem MFA, prod/production com header, `--non-interactive` não prompta mesmo com TTY); revisão #512: `agent canary start`, `servers provision` sem `--is-db-vm`, `admin database set-status` (sem 401 → sem MFA; retry com TOTP; `--json` fail-closed), `admin oidc-login rotate` (rota, body com/sem `immediate`, saída, fail-closed) e `bootstrap-admin --bootstrap-secret`/env (header enviado, valor nunca impresso, sessão opcional).
|
|
79
|
+
- `cli-mfa-destructive-surface.test.ts`: `servers provision` de app passa a exigir MFA (teste invertido); `agent canary start` e `servers provision` entram na enumeração destrutiva.
|
|
80
|
+
- **`api-error-401-shape.test.ts`** (novo): parser do 401 novo/legado/RFC/`mfa_required` via `fetch` stubado; mensagens e JSON do `handleApiError`.
|
|
81
|
+
- `ops-new-commands.test.ts` / `deploy.test.ts`: testes existentes de `migrate cli-keys` (aplicar) e `deploy --env prod` passam `mfaToken`; o de deploy afirma o header MFA no POST.
|
|
82
|
+
|
|
49
83
|
## [2.28.7] — 2026-09-07 (fix: `servers force-cleanup` sem step-up MFA — drift do P0.4)
|
|
50
84
|
|
|
51
85
|
### Corrigido
|
package/README.md
CHANGED
|
@@ -199,7 +199,8 @@ neetru audit tail --json | jq 'select(.action | startswith("billing"))'
|
|
|
199
199
|
- **Tokens** salvos em `~/.config/neetru-cli/auth.json` (chmod 0600 em Unix, NTFS ACL em Windows). Desde 2.11.0 o resolver canônico (`getActiveTokenSync`) prefere esse arquivo sobre o Conf storage legado (que será removido em 2.12.0)
|
|
200
200
|
- **URL allowlist** (desde 2.11.0): `neetruApiUrl` rejeita hosts fora de `*.neetru.com` + `localhost` sem `--allow-untrusted-url` — fecha vetor de exfiltração do Bearer token
|
|
201
201
|
- **Rate-limit** por método HTTP: GET 120/min, POST/PUT/PATCH 30/min, DELETE 5/min
|
|
202
|
-
- **Step-up MFA** (TOTP) obrigatório em operações destrutivas: `--mfa-token <code>` ou prompt
|
|
202
|
+
- **Step-up MFA** (TOTP) obrigatório em operações destrutivas: sessão de 1h (`neetru auth mfa-session`), `--mfa-token <code>` ou prompt (em `--json`/sem TTY: fail-closed). Desde 2.28.10 também em `agent release` (todos os canais), `ops reg-token`, `ops bootstrap-admin` (quando já há admin; `--reactivate` reativa staff desligado), `ops migrate cli-keys` (fora do dry-run), `vm provision` e `deploy --env prod`
|
|
203
|
+
- **`agent release`** só aceita binários em `https://core.neetru.com/releases/...` ou no bucket GCS de releases (validado localmente, mesma regra do Core)
|
|
203
204
|
- **Dry-run** disponível em comandos de mutação: `--dry-run` mostra efeito SEM aplicar
|
|
204
205
|
- **Telemetry** opt-in (desde 2.11.0): habilitando `telemetry.enabled=true` o CLI emite `{command, durationMs, ok, exitCode}` anônimo via `installId` UUID. Zero token/path/email/env vazam
|
|
205
206
|
|
|
@@ -9,6 +9,24 @@ export interface OidcLoginCreateOptions {
|
|
|
9
9
|
json?: boolean;
|
|
10
10
|
}
|
|
11
11
|
export declare function runOidcLoginCreate(opts: OidcLoginCreateOptions): Promise<void>;
|
|
12
|
+
export interface OidcLoginRotateOptions {
|
|
13
|
+
productId?: string;
|
|
14
|
+
/** `--immediate` — revoga o secret anterior na hora (sem a graça de 24h). */
|
|
15
|
+
immediate?: boolean;
|
|
16
|
+
mfaToken?: string;
|
|
17
|
+
json?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* `neetru admin oidc-login rotate <clientId> --product-id <id> [--immediate]`
|
|
21
|
+
*
|
|
22
|
+
* `POST /api/cli/v1/products/{productId}/oidc-login/rotate` (H4, auditoria
|
|
23
|
+
* cli/v1 2026-09-29). Mesmo contrato de `create`: o Core NÃO devolve o
|
|
24
|
+
* `client_secret` — grava a versão nova no Secret Manager e o PRÓXIMO deploy a
|
|
25
|
+
* injeta server-side. O secret anterior segue aceito até
|
|
26
|
+
* `previousSecretValidUntil` (24h); com `--immediate` ele é revogado na hora e o
|
|
27
|
+
* login do produto fica fora até o próximo deploy. Step-up MFA obrigatório.
|
|
28
|
+
*/
|
|
29
|
+
export declare function runOidcLoginRotate(clientId: string, opts: OidcLoginRotateOptions): Promise<void>;
|
|
12
30
|
export interface OidcLoginListOptions {
|
|
13
31
|
productId?: string;
|
|
14
32
|
json?: boolean;
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
* Sub-comandos:
|
|
14
14
|
* create — cria o login-client (PUBLIC/PKCE por default; --confidential p/ BFF)
|
|
15
15
|
* list — lista os login-clients do produto (mascarado, sem secret)
|
|
16
|
+
* rotate — rotaciona o client_secret (MFA; --immediate revoga o anterior na hora)
|
|
17
|
+
* rotate — rotaciona o client_secret (MFA; --immediate revoga o anterior na hora)
|
|
16
18
|
*
|
|
17
19
|
* Dois padrões de `redirect_uri` (o `/authorize` faz match EXATO byte-a-byte):
|
|
18
20
|
* - PUBLIC (PKCE client-side puro, ex.: NeetruLoginButton sem backend) → o SDK
|
|
@@ -23,6 +25,8 @@
|
|
|
23
25
|
* Endpoints (Core):
|
|
24
26
|
* GET /api/cli/v1/products/{productId}/oidc-login
|
|
25
27
|
* POST /api/cli/v1/products/{productId}/oidc-login
|
|
28
|
+
* POST /api/cli/v1/products/{productId}/oidc-login/rotate
|
|
29
|
+
* POST /api/cli/v1/products/{productId}/oidc-login/rotate
|
|
26
30
|
*/
|
|
27
31
|
import chalk from 'chalk';
|
|
28
32
|
import ora from 'ora';
|
|
@@ -111,6 +115,64 @@ export async function runOidcLoginCreate(opts) {
|
|
|
111
115
|
' bater com o que o SDK envia (PKCE client-side puro = a ORIGIN do produto).'));
|
|
112
116
|
console.log();
|
|
113
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* `neetru admin oidc-login rotate <clientId> --product-id <id> [--immediate]`
|
|
120
|
+
*
|
|
121
|
+
* `POST /api/cli/v1/products/{productId}/oidc-login/rotate` (H4, auditoria
|
|
122
|
+
* cli/v1 2026-09-29). Mesmo contrato de `create`: o Core NÃO devolve o
|
|
123
|
+
* `client_secret` — grava a versão nova no Secret Manager e o PRÓXIMO deploy a
|
|
124
|
+
* injeta server-side. O secret anterior segue aceito até
|
|
125
|
+
* `previousSecretValidUntil` (24h); com `--immediate` ele é revogado na hora e o
|
|
126
|
+
* login do produto fica fora até o próximo deploy. Step-up MFA obrigatório.
|
|
127
|
+
*/
|
|
128
|
+
export async function runOidcLoginRotate(clientId, opts) {
|
|
129
|
+
const token = await requireToken(opts.json);
|
|
130
|
+
function fail(message) {
|
|
131
|
+
if (opts.json) {
|
|
132
|
+
console.log(JSON.stringify({ ok: false, error: 'missing_param', message }));
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
log.error(message);
|
|
136
|
+
}
|
|
137
|
+
return safeExit(1);
|
|
138
|
+
}
|
|
139
|
+
if (!clientId || !clientId.trim())
|
|
140
|
+
fail('<clientId> é obrigatório.');
|
|
141
|
+
if (!opts.productId)
|
|
142
|
+
fail('--product-id é obrigatório.');
|
|
143
|
+
const { headers } = await resolveStepUp({ mfaToken: opts.mfaToken, json: opts.json });
|
|
144
|
+
const spinner = opts.json
|
|
145
|
+
? null
|
|
146
|
+
: ora({ text: `Rotacionando credencial de ${clientId}…`, color: 'blue' }).start();
|
|
147
|
+
let res;
|
|
148
|
+
try {
|
|
149
|
+
res = await apiRequest(`/api/cli/v1/products/${encodeURIComponent(opts.productId)}/oidc-login/rotate`, {
|
|
150
|
+
method: 'POST',
|
|
151
|
+
token,
|
|
152
|
+
headers,
|
|
153
|
+
body: { clientId: clientId.trim(), ...(opts.immediate ? { immediate: true } : {}) },
|
|
154
|
+
});
|
|
155
|
+
spinner?.stop();
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
spinner?.fail('Falha ao rotacionar a credencial.');
|
|
159
|
+
handleApiError(error, opts.json);
|
|
160
|
+
}
|
|
161
|
+
if (opts.json) {
|
|
162
|
+
console.log(JSON.stringify(res));
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
console.log();
|
|
166
|
+
log.success(`Credencial do login-client ${chalk.cyan(res.clientId)} rotacionada.`);
|
|
167
|
+
console.log(chalk.yellow(' NEETRU_CLIENT_SECRET novo → Secret Manager; NÃO é exibido. O próximo deploy o injeta server-side.'));
|
|
168
|
+
if (res.immediate || opts.immediate) {
|
|
169
|
+
console.log(chalk.red(' --immediate: o secret anterior JÁ NÃO VALE — o login do produto fica fora até o próximo deploy. Rode o deploy agora.'));
|
|
170
|
+
}
|
|
171
|
+
else if (res.previousSecretValidUntil) {
|
|
172
|
+
console.log(` ${chalk.dim('secret anterior aceito até')} ${res.previousSecretValidUntil} — faça o deploy antes disso.`);
|
|
173
|
+
}
|
|
174
|
+
console.log();
|
|
175
|
+
}
|
|
114
176
|
export async function runOidcLoginList(opts) {
|
|
115
177
|
const token = await requireToken(opts.json);
|
|
116
178
|
if (!opts.productId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oidc-login.js","sourceRoot":"","sources":["../../../src/commands/admin/oidc-login.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"oidc-login.js","sourceRoot":"","sources":["../../../src/commands/admin/oidc-login.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,5 +9,7 @@ export interface AgentReleaseOptions {
|
|
|
9
9
|
artifact?: string[];
|
|
10
10
|
/** se setado, só monta o payload e imprime, não chama API */
|
|
11
11
|
dryRun?: boolean;
|
|
12
|
+
/** `--mfa-token <código>` — TOTP do step-up MFA (pula o prompt interativo). */
|
|
13
|
+
mfaToken?: string;
|
|
12
14
|
}
|
|
13
15
|
export declare function runAgentRelease(opts: AgentReleaseOptions): Promise<void>;
|
|
@@ -11,6 +11,11 @@
|
|
|
11
11
|
* Backend: `POST api.neetru.com/cli/v1/agent/release` (Bearer token nrt_*),
|
|
12
12
|
* exige role `admin` em `cli_api_keys/{keyId}`.
|
|
13
13
|
*
|
|
14
|
+
* Auditoria cli/v1 2026-09-29 (H1): o Core exige step-up MFA em TODO canal
|
|
15
|
+
* (sessão de 1h via `neetru auth mfa-session` → `--mfa-token` → prompt TOTP) e
|
|
16
|
+
* só aceita `artifacts.<arch>.url` em `https://core.neetru.com/releases/...` ou
|
|
17
|
+
* no bucket GCS de releases — validado aqui ANTES de chamar a API.
|
|
18
|
+
*
|
|
14
19
|
* Roadmap:
|
|
15
20
|
* - Sprint futura: comando `--upload` que faz GCS upload + sha256 + register
|
|
16
21
|
* numa só chamada (precisa de credenciais GCP locais ou signed URL via Core).
|
|
@@ -23,12 +28,16 @@ import chalk from 'chalk';
|
|
|
23
28
|
import { log } from '../utils/logger.js';
|
|
24
29
|
import { apiRequest } from '../lib/api-client.js';
|
|
25
30
|
import { handleApiError } from '../lib/api-error.js';
|
|
31
|
+
import { resolveStepUp } from '../lib/cli-write.js';
|
|
32
|
+
import { AGENT_ARTIFACT_URL_HINT, agentReleasesBucket, isAllowedAgentArtifactUrl, } from '../lib/agent-artifact-url.js';
|
|
26
33
|
import { safeExit } from '../utils/safe-exit.js';
|
|
27
34
|
const VALID_CHANNELS = ['stable', 'beta', 'canary'];
|
|
28
35
|
const VALID_ARCHS = ['linux-x64', 'linux-arm64', 'darwin-x64', 'darwin-arm64'];
|
|
29
36
|
const SEMVER_RE = /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/;
|
|
30
37
|
const SHA256_RE = /^[a-f0-9]{64}$/;
|
|
31
|
-
|
|
38
|
+
function gcsBase() {
|
|
39
|
+
return `https://storage.googleapis.com/${agentReleasesBucket()}/releases`;
|
|
40
|
+
}
|
|
32
41
|
function isArch(s) {
|
|
33
42
|
return VALID_ARCHS.includes(s);
|
|
34
43
|
}
|
|
@@ -125,7 +134,7 @@ export async function runAgentRelease(opts) {
|
|
|
125
134
|
const { arch, filePath } = parseBinaryArg(a);
|
|
126
135
|
log.info(`Computando sha256 de ${chalk.dim(filePath)}...`);
|
|
127
136
|
const { sha256, sizeBytes } = await sha256File(filePath);
|
|
128
|
-
const url = `${
|
|
137
|
+
const url = `${gcsBase()}/${encodeURIComponent(opts.version)}/neetru-agent-${arch}`;
|
|
129
138
|
artifacts[arch] = { url, sha256, sizeBytes };
|
|
130
139
|
log.success(` ${arch}: sha256=${sha256.slice(0, 12)}... (${(sizeBytes / 1_000_000).toFixed(1)} MB)`);
|
|
131
140
|
log.dim(` URL: ${url}`);
|
|
@@ -154,6 +163,18 @@ export async function runAgentRelease(opts) {
|
|
|
154
163
|
safeExit(1);
|
|
155
164
|
return;
|
|
156
165
|
}
|
|
166
|
+
// H1 (auditoria cli/v1 2026-09-29): mesma allowlist de origem do Core —
|
|
167
|
+
// falha aqui, com mensagem clara, em vez de um 400 genérico da API.
|
|
168
|
+
const badUrls = Object.entries(artifacts).filter(([, a]) => !isAllowedAgentArtifactUrl(a.url));
|
|
169
|
+
if (badUrls.length > 0) {
|
|
170
|
+
for (const [arch, a] of badUrls) {
|
|
171
|
+
log.error(`--artifact ${arch}: URL fora da origem permitida de releases: ${a.url}`);
|
|
172
|
+
}
|
|
173
|
+
log.dim(` Origens aceitas: ${AGENT_ARTIFACT_URL_HINT}`);
|
|
174
|
+
log.dim(' Suba o binário pro bucket de releases (ou use --binary, que deriva a URL canônica).');
|
|
175
|
+
safeExit(1);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
157
178
|
// ── payload ─────────────────────────────────────────────────────────
|
|
158
179
|
const payload = {
|
|
159
180
|
version: opts.version,
|
|
@@ -169,9 +190,13 @@ export async function runAgentRelease(opts) {
|
|
|
169
190
|
return;
|
|
170
191
|
}
|
|
171
192
|
log.info(`Registrando release ${chalk.bold(opts.version)} (channel=${chalk.bold(channel)}, ${Object.keys(artifacts).length} arch(s))...`);
|
|
193
|
+
// H1: publicar release atinge a frota inteira via auto-update — step-up MFA
|
|
194
|
+
// obrigatório em todos os canais (mesmo fluxo de `agent yank`).
|
|
195
|
+
const { headers } = await resolveStepUp({ mfaToken: opts.mfaToken });
|
|
172
196
|
try {
|
|
173
197
|
const r = await apiRequest('/api/cli/v1/agent/release', {
|
|
174
198
|
method: 'POST',
|
|
199
|
+
headers,
|
|
175
200
|
body: payload,
|
|
176
201
|
});
|
|
177
202
|
if (r.alreadyExists) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-release.js","sourceRoot":"","sources":["../../src/commands/agent-release.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"agent-release.js","sourceRoot":"","sources":["../../src/commands/agent-release.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ export interface AgentYankOptions extends StepUpOptions {
|
|
|
5
5
|
export declare function runAgentYank(version: string, opts: AgentYankOptions): Promise<void>;
|
|
6
6
|
export declare function runAgentCanaryStart(version: string, opts: {
|
|
7
7
|
json?: boolean;
|
|
8
|
+
mfaToken?: string;
|
|
8
9
|
}): Promise<void>;
|
|
9
10
|
export interface AgentCanaryRollbackOptions extends StepUpOptions {
|
|
10
11
|
reason: string;
|
|
@@ -47,6 +47,9 @@ export async function runAgentCanaryStart(version, opts) {
|
|
|
47
47
|
safeExit(1);
|
|
48
48
|
}
|
|
49
49
|
const token = await requireToken(opts.json);
|
|
50
|
+
// Auditoria cli/v1 2026-09-29 (revisão): `start` empurra a versão pra parte da
|
|
51
|
+
// frota (5→25→100%) — o Core exige step-up MFA como no rollback.
|
|
52
|
+
const { headers } = await resolveStepUp({ mfaToken: opts.mfaToken, json: opts.json });
|
|
50
53
|
const spinner = opts.json
|
|
51
54
|
? null
|
|
52
55
|
: ora({ text: `Iniciando canary de ${version}…`, color: 'blue' }).start();
|
|
@@ -55,6 +58,7 @@ export async function runAgentCanaryStart(version, opts) {
|
|
|
55
58
|
res = await apiRequest('/api/cli/v1/agent/canary?action=start', {
|
|
56
59
|
method: 'POST',
|
|
57
60
|
token,
|
|
61
|
+
headers,
|
|
58
62
|
body: { version },
|
|
59
63
|
});
|
|
60
64
|
spinner?.stop();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-write.js","sourceRoot":"","sources":["../../src/commands/agent-write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EACL,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,GAEd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAMjD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAe,EACf,IAAsB;IAEtB,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,GAAG,CAAC,KAAK,CAAC,+DAA+D,CAAC,CAAC;QAC3E,QAAQ,CAAC,CAAC,CAAC,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,kBAAkB,CACtB,oBAAoB,OAAO,oDAAoD,EAC/E,IAAI,CACL,CAAC;IACF,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI;QACvB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,oBAAoB,OAAO,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;IACzE,IAAI,GAAgG,CAAC;IACrG,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,UAAU,CAAC,yBAAyB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE;YACnF,MAAM,EAAE,MAAM;YACd,KAAK;YACL,OAAO;YACP,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE;SACvC,CAAC,CAAC;QACH,OAAO,EAAE,IAAI,EAAE,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,IAAI,CAAC,0BAA0B,CAAC,CAAC;QAC1C,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IACD,gBAAgB,CACd,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,EAC/D,WAAW,GAAG,CAAC,OAAO,WAAW,EACjC,IAAI,CAAC,IAAI,CACV,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAAe,EACf,
|
|
1
|
+
{"version":3,"file":"agent-write.js","sourceRoot":"","sources":["../../src/commands/agent-write.ts"],"names":[],"mappings":"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"}
|
|
@@ -83,7 +83,22 @@ export interface DeployOptions {
|
|
|
83
83
|
* superfície HTTP (ex.: deploy de um serviço/worker sem endpoint web).
|
|
84
84
|
*/
|
|
85
85
|
skipHealthProbe?: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* `--mfa-token <código>` — TOTP do step-up MFA exigido pelo Core em deploy
|
|
88
|
+
* pra prod (auditoria cli/v1 2026-09-29, M7). Ignorado em dev/staging.
|
|
89
|
+
*/
|
|
90
|
+
mfaToken?: string;
|
|
86
91
|
}
|
|
92
|
+
/** `true` pra `prod`/`production` (o Core normaliza `production`→`prod`). */
|
|
93
|
+
export declare function isProdEnv(envName: string | undefined): boolean;
|
|
94
|
+
/**
|
|
95
|
+
* M7 (auditoria cli/v1 2026-09-29): `POST /api/cli/v1/deploy` com
|
|
96
|
+
* `environmentId` prod exige step-up MFA no Core (mesmo gate de `promote`).
|
|
97
|
+
* Resolve os headers (sessão 1h → --mfa-token → prompt TOTP; fail-closed em
|
|
98
|
+
* --json/--non-interactive/sem TTY) só quando o alvo é prod. Chamado logo
|
|
99
|
+
* antes do POST — depois do build/upload — pra o TOTP não vencer no meio.
|
|
100
|
+
*/
|
|
101
|
+
export declare function resolveDeployStepUpHeaders(opts: Pick<DeployOptions, 'mfaToken' | 'json'>, envName: string, nonInteractive: boolean): Promise<Record<string, string>>;
|
|
87
102
|
/**
|
|
88
103
|
* Mapeia o `envName` do deploy ('dev' | 'staging' | 'prod' — vocabulário do
|
|
89
104
|
* `--env` deste comando) pro `targetEnv` que `neetru build` entende
|
package/dist/commands/deploy.js
CHANGED
|
@@ -27,6 +27,7 @@ import ora from 'ora';
|
|
|
27
27
|
import { log } from '../utils/logger.js';
|
|
28
28
|
import { apiRequest, CliNetworkError } from '../lib/api-client.js';
|
|
29
29
|
import { handleApiError } from '../lib/api-error.js';
|
|
30
|
+
import { resolveStepUp } from '../lib/cli-write.js';
|
|
30
31
|
import { runBuild } from './build.js';
|
|
31
32
|
import { formatDeployConsole } from './deployments.js';
|
|
32
33
|
import { readDbJson, schemaFingerprint } from '../lib/db-local/index.js';
|
|
@@ -85,6 +86,28 @@ export function resolveDeployVersion(manifestVersion, explicitVersion, json) {
|
|
|
85
86
|
}
|
|
86
87
|
return version;
|
|
87
88
|
}
|
|
89
|
+
/** `true` pra `prod`/`production` (o Core normaliza `production`→`prod`). */
|
|
90
|
+
export function isProdEnv(envName) {
|
|
91
|
+
const e = (envName ?? '').trim().toLowerCase();
|
|
92
|
+
return e === 'prod' || e === 'production';
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* M7 (auditoria cli/v1 2026-09-29): `POST /api/cli/v1/deploy` com
|
|
96
|
+
* `environmentId` prod exige step-up MFA no Core (mesmo gate de `promote`).
|
|
97
|
+
* Resolve os headers (sessão 1h → --mfa-token → prompt TOTP; fail-closed em
|
|
98
|
+
* --json/--non-interactive/sem TTY) só quando o alvo é prod. Chamado logo
|
|
99
|
+
* antes do POST — depois do build/upload — pra o TOTP não vencer no meio.
|
|
100
|
+
*/
|
|
101
|
+
export async function resolveDeployStepUpHeaders(opts, envName, nonInteractive) {
|
|
102
|
+
if (!isProdEnv(envName))
|
|
103
|
+
return {};
|
|
104
|
+
const { headers } = await resolveStepUp({
|
|
105
|
+
mfaToken: opts.mfaToken,
|
|
106
|
+
json: opts.json,
|
|
107
|
+
nonInteractive,
|
|
108
|
+
});
|
|
109
|
+
return headers;
|
|
110
|
+
}
|
|
88
111
|
const TERMINAL_STATUSES = new Set(['success', 'failed', 'cancelled']);
|
|
89
112
|
/** Estágios de ambiente válidos para o deploy workspace. */
|
|
90
113
|
const WORKSPACE_ENVS = new Set(['dev', 'staging', 'prod']);
|
|
@@ -991,6 +1014,7 @@ async function runWorkspaceDeploy(opts, productSlug, envName, cwd, nonInteractiv
|
|
|
991
1014
|
source: source.content,
|
|
992
1015
|
};
|
|
993
1016
|
}
|
|
1017
|
+
const mfaHeaders = await resolveDeployStepUpHeaders(opts, envName, nonInteractive);
|
|
994
1018
|
const spinner = ora({
|
|
995
1019
|
text: 'Publicando no workspace (build + deploy)…',
|
|
996
1020
|
color: 'blue',
|
|
@@ -999,6 +1023,7 @@ async function runWorkspaceDeploy(opts, productSlug, envName, cwd, nonInteractiv
|
|
|
999
1023
|
try {
|
|
1000
1024
|
resp = await apiRequest('/api/cli/v1/deploy', {
|
|
1001
1025
|
method: 'POST',
|
|
1026
|
+
headers: mfaHeaders,
|
|
1002
1027
|
body: deployBody,
|
|
1003
1028
|
});
|
|
1004
1029
|
}
|
|
@@ -1360,11 +1385,13 @@ async function runCloudRunDeploy(opts, productSlug, envName, cwd, nonInteractive
|
|
|
1360
1385
|
safeExit(0);
|
|
1361
1386
|
}
|
|
1362
1387
|
}
|
|
1388
|
+
const mfaHeaders = await resolveDeployStepUpHeaders(opts, envName, nonInteractive);
|
|
1363
1389
|
const spinner = ora({ text: 'Publicando no Cloud Run…', color: 'blue' }).start();
|
|
1364
1390
|
let resp;
|
|
1365
1391
|
try {
|
|
1366
1392
|
resp = await apiRequest('/api/cli/v1/deploy', {
|
|
1367
1393
|
method: 'POST',
|
|
1394
|
+
headers: mfaHeaders,
|
|
1368
1395
|
body: {
|
|
1369
1396
|
productSlug,
|
|
1370
1397
|
version: resolveDeployVersion(undefined, opts.version, opts.json),
|
|
@@ -1598,11 +1625,13 @@ export async function runDeploy(opts) {
|
|
|
1598
1625
|
body.domain = domain;
|
|
1599
1626
|
if (envVars && Object.keys(envVars).length > 0)
|
|
1600
1627
|
body.envVars = envVars;
|
|
1628
|
+
const mfaHeaders = await resolveDeployStepUpHeaders(opts, envName, nonInteractive);
|
|
1601
1629
|
let deploy;
|
|
1602
1630
|
const dispatchSpinner = ora({ text: 'Enviando comando ao Core…', color: 'blue' }).start();
|
|
1603
1631
|
try {
|
|
1604
1632
|
deploy = await apiRequest('/api/cli/v1/deploy', {
|
|
1605
1633
|
method: 'POST',
|
|
1634
|
+
headers: mfaHeaders,
|
|
1606
1635
|
body,
|
|
1607
1636
|
});
|
|
1608
1637
|
dispatchSpinner.succeed(`Deploy criado: ${chalk.bold(deploy.deploymentId)}`);
|