feat/tb-deploy
needs attentionviewing older commitb7800c0 · incrementalPR #261reviewed 2026-07-07 03:31 UTC1H · 2M · 7L · 5I- Purpose
- Establish Batu's Tinybird deployment strategy: three long-lived workspaces (batu_dev/stg/prod) for hard isolation, ephemeral Forward branches per PR inside dev, and a per-environment token split replacing the single shared TINYBIRD_TOKEN.
- Goal
- No admin token seeded to runtime — every seeded token is least-privilege (append+read); all privileged tokens are CI-only.
- Sub-goals
- SG-1: Strategy rule doc + README de-stale; scoped-runtime-vs-deploy-token split
- SG-2: Per-env metrics-SSM seed (preview/staging/prod)
- SG-3: Vercel per-env tokens (operator action + doc)
- SG-4: Ephemeral per-PR Tinybird branch + cleanup
- SG-5: Schema-CD — tinybird-staging / tinybird-prod jobs, CI-only WORKSPACE:DEPLOY token
- SG-6: Fold per-env tokens + schema-CD lane into infrastructure.md / migration-pipeline.md
- What
- This incremental commit completes the dev token split: TINYBIRD_TOKEN_DEV demoted from admin to runtime (append+read); new TINYBIRD_DEPLOY_TOKEN_DEV (ADMIN, CI-only) takes over branch creation/deletion and schema-check. Three workflows and two rule/doc files updated.
- Why
- Having an admin token seeded to dev SSM/Vercel was a known dev-only trade-off accepted earlier in the branch. This commit closes that gap so the invariant holds across all environments.
- Areas
- .claude/rules+272−2.github/workflows+304−41infra/tinybird+175−43
- Blast
- 11 files, +718/−91 across CI workflows, Tinybird infra, and Claude rule docs. No application TypeScript, no database schema changes.
Findings · 15
correctness2
Stale 'admin token' comment on SSM fallback path
.github/workflows/preview-provision.yml:821
A comment block near the SSM seed step still describes TINYBIRD_TOKEN_DEV as the 'admin token' fallback. Post-split it is the runtime (append+read) token. The code is correct but the comment directly contradicts the invariant the PR establishes.
Vercel fallback uses TINYBIRD_TOKEN, SSM fallback uses TINYBIRD_TOKEN_DEV — asymmetry post-split
.github/workflows/preview-provision.yml:453
Pre-existing asymmetry: Vercel falls back to legacy TINYBIRD_TOKEN; SSM falls back to TINYBIRD_TOKEN_DEV. Not introduced by this diff, but operators must keep both populated as the token landscape stabilises.
security4
Extracted branch token flows through GITHUB_OUTPUT — masked but expressions expand pre-mask
.github/workflows/preview-provision.yml:341
Branch token is masked with ::add-mask:: before GITHUB_OUTPUT write, but expressions (${{ steps.tb_provision.outputs.tb_branch_token }}) expand before the mask applies — known GitHub Actions limitation. Bounded blast radius since this is a runtime (append+read) token, not admin. Pre-existing pattern.
Legacy TINYBIRD_TOKEN echoed to GITHUB_OUTPUT without masking
.github/workflows/preview-provision.yml:282
The 'Configure Tinybird workspace token for Vercel' step echoes TINYBIRD_TOKEN into GITHUB_OUTPUT without ::add-mask::. Could appear in debug logs if step debug logging is enabled. Pre-existing; not introduced by this diff.
TINYBIRD_DEPLOY_TOKEN_DEV correctly CI-only: never seeded to SSM/Vercel
.github/workflows/preview-provision.yml:303
Admin token is consumed only in the branch provisioning step and never assigned to any GITHUB_OUTPUT variable, SSM parameter, or Vercel env var. Separation is clean.
pr-checks on pull_request (not pull_request_target) — no fork secret exposure
.github/workflows/pr-checks.yml:3
Secrets unavailable to fork PRs; empty-token guard skips gracefully. No fork privilege escalation risk.
conventions5
Operator runbook creates dev deploy token with wrong scope (WORKSPACE:DEPLOY instead of ADMIN)
.claude/rules/tinybird-deployment.md:222
The runbook step 2 shows `tb --cloud token create static ci_deploy --scope WORKSPACE:DEPLOY` and groups all deploy tokens (including _DEV) under that command. But the rule file itself and infrastructure.md establish that TINYBIRD_DEPLOY_TOKEN_DEV requires ADMIN scope — WORKSPACE:DEPLOY is refused for `tb --cloud preview`. An operator following the runbook verbatim would mint an under-scoped token and hit a cryptic 403 at runtime. The runbook needs a separate sub-step for dev using ADMIN scope.
Per-PR branch flow still says gated on TINYBIRD_TOKEN_DEV (should be TINYBIRD_DEPLOY_TOKEN_DEV)
.claude/rules/tinybird-deployment.md:166
The per-PR branch flow description (step 2) still reads 'gated on TINYBIRD_TOKEN_DEV' — the old admin token. Post-split the provisioning step is gated on TINYBIRD_DEPLOY_TOKEN_DEV. This will confuse operators debugging a failing provision step.
infrastructure.md 'How to get' says tb token copy ci_admin but runbook says ci_deploy
.claude/rules/infrastructure.md:258
The manifest says TINYBIRD_DEPLOY_TOKEN_DEV is obtained via `tb token copy ci_admin`. The runbook at tinybird-deployment.md shows `tb --cloud token create static ci_deploy --scope WORKSPACE:DEPLOY` for all deploy tokens. Token name and creation command disagree between the two SSOT files — operators get conflicting guidance.
preview-provision.yml inline comment near SSM seed still describes TINYBIRD_TOKEN_DEV as admin
.github/workflows/preview-provision.yml:782
Comment block at line 782 refers to TINYBIRD_TOKEN_DEV without clarifying its post-split role as a runtime token. A reader comparing it to TINYBIRD_DEPLOY_TOKEN_DEV at line 303 may be confused about the role split.
tinybird-deployment.md three-lane seeding table may conflate provision token with runtime seed token
.claude/rules/tinybird-deployment.md:183
The preview lane shows 'branch token ⊳ TINYBIRD_TOKEN_DEV'. A reader could conflate this with the provisioning token (TINYBIRD_DEPLOY_TOKEN_DEV). A parenthetical clarifying the column represents the seeded runtime token would prevent confusion.
tests2
Secret name typo would silently degrade to skip-path rather than failing loudly
.github/workflows/pr-checks.yml:411
No workflow-level test harness exists. A typo in the secret name silently degrades to skip-with-warning rather than failing the check. Acceptable for a CI-only secret-reference rename with no logic change.
Manual test plan in commit message is credible and sufficient
.github/workflows/preview-provision.yml:1
Commit documents: deployment #1 bootstrapped batu_dev with scoped metrics_runtime token, all seeded tokens now append+read only. Consistent with the completed operator actions described in the PR.
improvement2
Three workflows repeat the same admin-scope explanation inline
.github/workflows/pr-checks.yml:413
The explanation of why TINYBIRD_DEPLOY_TOKEN_DEV requires admin scope is repeated in pr-checks.yml, preview-deprovision.yml, and preview-provision.yml. A future secret addition would require updating all three. Single authoritative callout in tinybird-deployment.md with per-step comments shrunk to just the reference would be cleaner.
Inline provision step comment is proportionate and load-bearing — keep
.github/workflows/preview-provision.yml:288
The three-line comment explaining the extract-then-seed pattern and the admin/runtime distinction is worth keeping. Without it the reason for two separate token secrets is invisible from the YAML.
History · 10 commits
- 5d30429safeincremental0H · 0M · 1L2026-07-08 23:04
- 19bac85needs attentionincremental0H · 5M · 6L2026-07-08 22:46
- 92e890aneeds attentionincremental0H · 1M · 3L2026-07-08 21:46
- e81a781needs attentionincremental0H · 4M · 4L2026-07-08 21:31
- 2eca91cneeds attentionfull5H · 13M · 12L2026-07-08 19:18
- cf63bb1needs attentionincremental4H · 4M · 7L2026-07-07 19:47
- f43d034needs attentionincremental2H · 3M · 3L2026-07-07 18:35
- b7800c0needs attentionincremental1H · 2M · 7L2026-07-07 03:31current
- 5aef105needs attentionfull6H · 9M · 2L2026-07-06 17:52
- 95b4484blockedfull3H · 8M · 4L2026-07-06 05:36