Skip to content

Porter deployment onboarding: checklist, deploy reference, first-admin guardrails - #911

Merged
16francej merged 2 commits into
mainfrom
porter-onboarding
Sep 3, 2026
Merged

Porter deployment onboarding: checklist, deploy reference, first-admin guardrails#911
16francej merged 2 commits into
mainfrom
porter-onboarding

Conversation

@16francej

@16francej 16francej commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Stacked on #910 (it extends the same docs/porter.md; retarget to main once #910 merges).

Why

First-hand Porter onboarding feedback: nothing tells a new operator (or the deploying agent) to link a cloud account, which token role to mint, or to name an administrator — and with Postgres, a missed ADMIN_GRANTS yields a running instance whose admin console can never be unlocked from inside the product. The porter CLI is used throughout the docs without ever being declared a prerequisite.

What

  • Onboarding checklist at the top of docs/porter.md: cloud account linked (check GET .../cloud-accounts first, prompt the operator to link at dashboard.porter.run/cloud-accounts if not — with the us-east-2 SCP and account-ID gotchas), Admin-role API token (Developer tokens die mid-deploy with PERMISSION_DENIED), sandbox ingress in the creation contract, administrator email before first boot, then build/apply/verify. Written for agents: use the operator's browser for dashboard steps when available, otherwise hand over the exact URL; prefer the porter CLI over raw API calls.
  • references/porter.md in the deployment workflow (mirroring fly.md/aws.md, plus the .codex stub), and Porter added to deployment.md's hosting-target choice with an honest note that it has no qm CLI target.
  • Secret spec: PORTER_DEPLOY_API_TOKEN now says Admin-role and carries a generate hint (dashboard → Settings → API tokens).
  • Boot guardrail: core warns when DATABASE_URL is set with no ADMIN_GRANTS, naming the first-admin lockout and the exact fix.

Verification

test/deployment-skill.test.ts extended (porter reference phrases, file presence in both reference dirs, workflow routing); cli/test/package.test.ts pins the new template in the published package; cli secrets/init suites, public-architecture-docs, typecheck, eslint, oxlint, prettier all green locally.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Base automatically changed from tiered-app-serving to main September 3, 2026 03:49
16francej and others added 2 commits September 2, 2026 20:49
…rdrails

Porter had no onboarding path: docs/porter.md was post-hoc field notes, the
cloud-account prerequisite appeared nowhere in the repo, the Admin-vs-Developer
token requirement was stranded 180 lines below where the token is introduced,
the porter CLI was used but never declared, and ADMIN_GRANTS — without which a
Postgres-backed instance boots with a permanently unreachable admin console —
was missing from the Porter path entirely.

- docs/porter.md gains an onboarding checklist up top: linked cloud account
  (with the region-SCP and account-ID field gotchas), Admin-role API token,
  sandbox ingress in the creation contract, administrator email before first
  boot, then build/apply/verify — with agent-with-browser vs hand-the-operator-
  the-URL guidance.
- cli/templates/deployment/references/porter.md (+ .codex stub) brings Porter
  into the deployment workflow following the fly.md/aws.md pattern, and
  deployment.md's provider choice now names Porter with its manual path.
- PORTER_DEPLOY_API_TOKEN's secret spec names the Admin-role requirement and
  gains a generate hint pointing at the dashboard.
- Core boot warns when a durable store has no ADMIN_GRANTS, naming the
  first-admin lockout and its fix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ions

From a live Porter test deployment on main:

- Auth misreported a core outage as "per-address rate limit reached":
  coreClaimStore mapped every transport failure and 5xx to null, which
  withinRateLimit read as an exhausted slot. The claim store now throws a
  typed ClaimStoreUnavailableError; sign-in still fails closed but says core
  is unreachable, link verification answers a retryable 503 ("temporarily
  unavailable", link stays valid) instead of the dead-end stale-link page,
  token exchange answers temporarily_unavailable, and the playground mint
  keeps its 429 with an honest log. Auth gains /readyz, which probes core's
  /healthz so orchestrators can gate traffic on the dependency.
- docs/porter.md no longer claims Porter creates the Route53 hosted zone —
  confirmed against Porter's team and live DNS that the dedicated zone, NS
  delegation, and wildcard record are the operator's to create, with the
  reconcile step that then mints the issuer.
- Onboarding checklist and porter reference gain the DATABASE_URL step
  (sign-in hard-requires the durable store; no CLI provisioning on Porter;
  API-created RDS can name the cluster in connected_cluster_ids while its
  security group refuses it), the porter-dev tap vs Homebrew-core `porter`
  collision plus docker-credential-porter, app-level env in v2 YAML, and
  ECR repositories not auto-created on push.
- porter/apps/egress-proxy.yaml documents why it is a worker and what makes
  egress enforced rather than fail-open (LoadBalancer in front, sandboxes
  cannot reach RFC1918 and the web ingress cannot carry CONNECT).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@16francej
16francej merged commit f65fc82 into main Sep 3, 2026
20 checks passed
@16francej
16francej deleted the porter-onboarding branch September 3, 2026 03:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant