← all branches

feat/tb-deploy

needs attentionviewing older commit
b7800c0 · incrementalPR #261reviewed 2026-07-07 03:31 UTC1H · 2M · 7L · 5I
The branch
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
The changes (whole branch)
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+2722.github/workflows+30441infra/tinybird+17543
Blast
11 files, +718/−91 across CI workflows, Tinybird infra, and Claude rule docs. No application TypeScript, no database schema changes.
ci-only infra secrets no-ts-changes
ci-checks· elevated token not available in this runner contextcoderabbit· no .coderabbit.yaml in repo

Findings · 15

correctness2

low

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.

info

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

low

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.

low

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.

info

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.

info

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

high

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.

medium

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.

medium

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.

low

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.

low

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

low

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.

info

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

low

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.

info

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

  1. 5d30429safeincremental0H · 0M · 1L2026-07-08 23:04
  2. 19bac85needs attentionincremental0H · 5M · 6L2026-07-08 22:46
  3. 92e890aneeds attentionincremental0H · 1M · 3L2026-07-08 21:46
  4. e81a781needs attentionincremental0H · 4M · 4L2026-07-08 21:31
  5. 2eca91cneeds attentionfull5H · 13M · 12L2026-07-08 19:18
  6. cf63bb1needs attentionincremental4H · 4M · 7L2026-07-07 19:47
  7. f43d034needs attentionincremental2H · 3M · 3L2026-07-07 18:35
  8. b7800c0needs attentionincremental1H · 2M · 7L2026-07-07 03:31current
  9. 5aef105needs attentionfull6H · 9M · 2L2026-07-06 17:52
  10. 95b4484blockedfull3H · 8M · 4L2026-07-06 05:36