Skip to main content
0.0.x

Team Workspace

Picture the app this track is modeled on: a production context-accumulator chat application built on NetScript. An operations team lives in it during an ERP cutover — projects and channels full of live incident context, diagnostics, and half-finished conclusions about a production system that is misbehaving right now. Underneath all of that sits an unglamorous layer that decides everything: who is on the team, where their data lives, and which routes they may touch. Get it wrong in one direction and an off-boarded contractor can still read incident channels; get it wrong in the other and the engineer you just paged is locked out while production burns.

The differentiator this track proves is that the identity layer is NetScript's to ship, not yours to rebuild: a pluggable auth backend, a normalized session, and a typed .withAuthn() / .withAuthz() route seam — in place of the bespoke sign-in flow and hand-rolled route middleware most stacks reimplement, and re-secure, once per app.

That layer is what you build here, from an empty folder to a running, session-protected app under Aspire: you scaffold a workspace (Postgres by default, swappable to mysql, mssql, or sqlite via --db), sign users in through a pluggable auth backend, give team records their own isolated database, provision new members with a background job that never blocks the caller, and gate your service routes with the real .withAuthz() seam. It is one continuous app — your my-workspace/ grows with every chapter.

  1. 1 · Scaffold
  2. 2 · Auth
  3. 3 · Workspace data
  4. 4 · Provision job
  5. 5 · Route authz
  6. 6 · Deploy

What you will build

By the end of this track you will have a NetScript workspace that signs a real user in through an OAuth/OIDC provider, mints a session cookie, stores team records in their own isolated Postgres (the default; or mysql / mssql / sqlite via --db), provisions a new member off the request path with a background job, and rejects unauthenticated requests to its guarded routes with a 401 — all running locally under one Aspire dashboard. The central idea: authentication in NetScript is a pluggable backend, a session, and a route-authz seam — not a bespoke rewrite you carry yourself.

The arc: auth → session → authz

Three ideas carry the whole track, and each chapter adds exactly one:

  • Auth — a backend turns a sign-in into an identity. You pick one of three backends (kv-oauth, workos, better-auth) with an environment variable; the contract is identical across all three.
  • Session — a successful sign-in mints a normalized AuthSession and sets a session cookie. Every later request resolves the current session from that cookie.
  • Authz — a service gates its own routes with .withAuthn() (resolve a Principal) and .withAuthz() (decide from it). This is route-level authorization, scoped to route-level — not org/role RBAC.

Who this is for

You should be comfortable with the basics from the core tutorial ladder — scaffolding a workspace, the contract → service flow, and bringing up Aspire. This track does not re-teach those; it assumes you can scaffold and boot, then layers authentication on top. If netscript init and aspire start are new to you, walk the Quickstart first.

The six chapters

What you built

A clear map of the track: the team layer that a real operations tool stands on — a pluggable auth backend, a session, isolated team data, off-path provisioning, and a route-authz seam that fails closed. Single-tenant by design, with org scoping as an explicit app-level extension. Start at chapter 1 and keep the same my-workspace/ through to deploy.

After this track, keep building in Build › Identity & Access — the guides and recipes there pick up where these chapters stop.