Neon Law
  • Fractional CTO
  • Litigation
  • Fractional GC
  • Legal Services
  • Sign in
← Operating Neon Law Navigator

Prepare Google Cloud

Chapter 2 of 7 · Section 10 of 44

Sections

1. Intro

  • 1. Deploy your own
  • 2. Agenda

2. Prepare Google Cloud

  • 3. Bring your own project
  • 4. Dry-run first
  • 5. Private assets and domain restricted sharing
  • 6. The one project that is public on purpose
  • 7. The Navigator deployment matrix
  • 8. The `/app` mount and HTTP route ownership
  • 9. `neon` — the whole brand seam
  • 10. Live rollout checkpoint
  • 11. Set one site to one version

3. Provision the Infrastructure

  • 12. The APIs that light up
  • 13. Network and five buckets
  • 14. How a Project portal reaches a client
  • 15. One matter's document never backs another matter's
  • 16. A private image registry
  • 17. The cluster comes up

4. Environment Matrix

  • 18. Three operating modes, two deployment profiles
  • 19. Configuration precedence: the first source wins
  • 20. Local dev controls: inputs read by `navigator dev`
  • 21. Local runtime: what `.devx/env` generates
  • 22. The store: SurrealDB
  • 23. Where SurrealDB authorization lives
  • 24. Deployed runtime: core web and worker wiring
  • 25. Deployed runtime: identity and access
  • 26. Deployed runtime: email, signatures, and billing
  • 27. Deployed runtime: repositories, content, AI, and scheduled work
  • 28. Provision and ship: variables read by the operator CLI
  • 29. Ancillary operations and opt-in test controls
  • 30. When simulated data appears

5. Configure the Trust Boundaries

  • 31. Secrets: the invariants that gate the boot
  • 32. Sign-in: bring an OIDC provider; passwords live there, not here
  • 33. Role rings: who can do what
  • 34. Provider signup and parity across the deployments
  • 35. The external surface — every third party, in one place
  • 36. The two service deployments
  • 37. Security architecture

6. Ship the Instance

  • 38. Ship and verify
  • 39. Post the verified handoff in `#navigator`
  • 40. Point your domain at the instance (optional)
  • 41. Drive it from the CLI
  • 42. Make it yours — white-label under your own brand
  • 43. This is how we set up Neon Law Foundation

7. Wrap Up

  • 44. Canonical references

Live rollout checkpoint

As of 31 July 2026, the two production substrates have completed every setup stage, and neon-law-stg is a created but unprovisioned project:

  • Both production GKE Autopilot clusters are RUNNING in us-west4, and no deployment reads Postgres: ENG-22 moved the store to SurrealDB, /health pings SurrealDB, and ops gcp setup provisions no Cloud SQL instance, so a deleted one is not recreated on the next run. An operator must export the two legacy production Postgres 15 instances to each deployment's own exports bucket and then delete them. Nothing has ever archived those instances — the nightly archive lane covers the SurrealDB tables only — so the export is what makes the deletion reversible, and it is not optional.
  • neon-law-stg and ghcr exist in the neonlaw.com organization and are linked to billing, but neither has been through its provisioner yet. Run ops gcp hub setup against the hub first, then ops gcp setup against staging — the environment provisioner grants against the hub repository, so the hub must exist before any environment names it.
  • Each provisioned row has five private assets, documents, exports, logs, and applications buckets.
  • On those rows, both the deployment runtime identity and the active operator have bucket-scoped roles/storage.objectAdmin; none of the buckets grants allUsers.

The five-bucket list is the current checkpoint, not the target topology. Issue #1103 coordinates the migration to exactly one private object-storage bucket per deployment and never one bucket per Project. Project growth adds rows and logical key space, with lanes such as {project-code}/documents/ and {project-code}/exports/ inside the deployment bucket; it does not create cloud buckets. Marketing bytes remain available through the same-origin /assets/* application route while the bucket itself stays private and does not grant allUsers. Until that atomic migration lands, setup reconciles the five existing bucket resources recorded above.

New clusters are created with --enable-fleet; the subsequent idempotent reconciliation can therefore report Changing existing fleet membership is not supported. Navigator treats only that exact response as already reconciled and continues; unrelated Fleet errors still stop setup.

Infrastructure is not deployment. The two production clusters currently have no application namespace, Deployment, Service, Gateway, or HTTPRoute, so their public hosts do not yet answer TLS. An operator must ship one immutable release to Neon production and Neon Law production, then prove /readyz, /version, certificate readiness, Restate registration, and the browser surface before posting the #navigator handoff.

For a prefix <name>, set NAVIGATOR_GKE_CLUSTER_NAME=<name>, NAVIGATOR_GKE_CONTEXT=gke_<project>_<region>_<name>, NAVIGATOR_K8S_NAMESPACE=<name>, NAVIGATOR_VPC_NAME=<name>-vpc, NAVIGATOR_SUBNETWORK_NAME=<name>-subnet, NAVIGATOR_GATEWAY_IP_NAME=<name>-gateway-ip, NAVIGATOR_ASSETS_BUCKET=<name>-assets, NAVIGATOR_DOCUMENTS_BUCKET=<name>-documents, NAVIGATOR_EXPORTS_BUCKET=<name>-exports, NAVIGATOR_LOGS_BUCKET=<name>-logs, NAVIGATOR_APPLICATIONS_BUCKET=<name>-applications, NAVIGATOR_GCP_SERVICE_ACCOUNT_ID=<name>-web, NAVIGATOR_DRIVE_GCP_SERVICE_ACCOUNT_ID=<name>-drive, and NAVIGATOR_WEB_SECRET_NAME=<name>-web-secrets. Bucket names are global; add one stable organization prefix if a short bucket name is already taken.

Also set NAVIGATOR_GCP_PROJECT_ID, NAVIGATOR_GCP_LOCATION, NAVIGATOR_PUBLIC_HOST, NAVIGATOR_WORKFLOWS_HOST, NAV_BASE_URL=https://$NAVIGATOR_PUBLIC_HOST, NAVIGATOR_WORKFLOWS_URL=https://$NAVIGATOR_WORKFLOWS_HOST/, NAVIGATOR_WEB_IMAGE, and NAVIGATOR_ASSET_BASE_URL=$NAV_BASE_URL/assets in that deployment's deployments/<name>/config.toml. Set that row's own NAVIGATOR_SURREAL_* coordinates and credentials in its secrets.enc.yaml.

Keep the mail rail complete in every deployment's secrets.enc.yaml: SENDGRID_API_KEY, SENDGRID_FROM_EMAIL, SENDGRID_INBOUND_SECRET, SENDGRID_EVENTS_SECRET, and SENDGRID_EVENTS_PUBLIC_KEY; staging uses non-production SendGrid credentials and production uses live credentials authenticated for its domain.

Provision each row with the same region-agnostic command — one run per deployments/ directory, its coordinates exported from that directory's config.toml (populate the directory first; the config is the source of every coordinate the provisioner reads, so a row is provisioned only once its directory exists). Each run creates five buckets and one Autopilot cluster; re-running reconciles only that row:


set -a; eval "$(grep ' = "' deployments/neon-law-stg/config.toml | sed 's/ = /=/')"; set +a
navigator ops gcp setup --dry-run

Check every printed project, region, resource prefix, and the two API batches. Provision the registry hub once before the runtime stacks; it runs no workloads:


navigator ops gcp hub setup \
  --project-id ghcr --region us-west4 --dry-run
navigator ops gcp hub setup \
  --project-id ghcr --region us-west4

Then apply the already-reviewed plans one deployment at a time. Keep staging first, and do not begin production until its command finishes:


set -a; eval "$(grep ' = "' deployments/neon-law-stg/config.toml | sed 's/ = /=/')"; set +a
navigator ops gcp setup

That is the live resource boundary, per deployment: five buckets, one VPC/subnet pair, one reserved gateway address, one Autopilot cluster, one KMS key, and two deployment service accounts. The command also enables the twenty-two required APIs in that runtime project. A completed command is not yet a deployed website; ops ship, DNS, and the browser checks later in this workshop remain required.

Setup provisions no database and generates no credential, so there is nothing printed to record. The store's own credentials go into deployments/<name>/secrets.enc.yaml (sops set — the plaintext never touches disk), then navigator ops secrets apply --deployment <name>; rotation happens at the provider first, per docs/deployment-secrets.md.

Resolve every reserved address and record the public value as NAVIGATOR_GATEWAY_IP in the matching config.toml — an IP is a public coordinate, so it is edited and committed like any other:


for name in $(ls deployments); do
  set -a; eval "$(grep ' = "' "deployments/${name}/config.toml" | sed 's/ = /=/')"; set +a
  echo "${name}:"
  gcloud compute addresses describe "$NAVIGATOR_GATEWAY_IP_NAME" \
    --global --project "$NAVIGATOR_GCP_PROJECT_ID" --format 'value(address)'
done

Populate the matching local Kubernetes context before shipping a row:


set -a; eval "$(grep ' = "' deployments/neon-law-stg/config.toml | sed 's/ = /=/')"; set +a
gcloud container clusters get-credentials \
  "$NAVIGATOR_GKE_CLUSTER_NAME" --region "$NAVIGATOR_GCP_LOCATION" \
  --project "$NAVIGATOR_GCP_PROJECT_ID"

The resulting context name must equal that config's NAVIGATOR_GKE_CONTEXT. Repeat once for each deployment you are operating.

The canonical matrix is the compact reference for every row.

Presenter notes

Pause on the isolation boundary: staging proves the shared mounted application, while the production data planes stay isolated. Point to the resource prefix column and verify that every database, bucket set, cluster, namespace, service account, Secret, and gateway address carries the row's prefix. Then demonstrate the dry run before discussing any billable live command.

View all slidesOpen display
← PreviousNext →
Neon Law
BlogContactFoundationNavigatorPresentationsWorkshops
Contact us — contact@neonlaw.com+1 510 800 2080
  • Nevada
    5150 Mae Anne AveSte 405-9002Reno, NV 89523
  • New York
    12 E 49th St18th FloorNew York, NY 10017
  • Washington
    720 Seneca StSte 107-715Seattle, WA 98101

© 2026 Shook Law PLLC and Neon Law Foundation

This is attorney advertisement. Nothing on this site is legal advice. Neon Law is the trade name of Shook Law PLLC, and an attorney-client relationship begins only with a signed retainer between you and Shook Law PLLC. Published flat fees cover the scope each one names and do not include third-party filing fees. Every legal matter is different, and past results do not guarantee a similar result.

Shook Law PLLC is a proud supporter of the Neon Law Foundation , a 501(c)(3) nonprofit.

Neon Law Foundation is a Nevada nonprofit corporation and a 501(c)(3) tax-exempt organization. It does not practice law and cannot represent you.

Nothing on this site is legal advice, and nothing here creates an attorney-client relationship.

5150 Mae Anne Ave Ste 405-9999, Reno, NV 89523
support@neonlaw.orgTransparency & public disclosures

Powered by Neon Law Navigator #26.8.20-hotfix.4

Open source — neon-law-foundation/navigator GitHub stars 2