diff --git a/.gitignore b/.gitignore
index fa86c33..ca32a63 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,7 +10,7 @@ IGNORE-ME*
 .draft
 
 # local env files
-.env*
+.env*.local
 
 # local certs
 local_dev/config/cert.pem
diff --git a/README.md b/README.md
index e69b077..f314637 100644
--- a/README.md
+++ b/README.md
@@ -1,39 +1,100 @@
 # DRAFT - Distributed Relay and Automation Facilitation Tool
 ![image of a draft beer tap](server/public/beer-tap.png)
 
-draft is a project designed to help test [IPA](https://github.com/private-attribution/ipa) at scale. It contains 2 components:
+draft is a project designed to help test [IPA](https://github.com/private-attribution/ipa) at scale. It contains two components:
 
-1. draft-server: a web front end and service that starts queries an displays logs from the MPC helper servers
-2. draft-sidecar: a sidecar back end API that runs next to the IPA binary on helper servers. This includes a CLI for setup and running.
+1. draft-server: a web front end and service that starts queries and displays logs from the MPC helper servers.
+2. draft-sidecar: a sidecar backend API that runs next to the IPA binary on helper servers. This includes a CLI for setup and running.
 
-# Get started
 
-## Local Dev
+# Get started
 
+## Deploying a Helper Party
 
-### Running Locally
+### Requirements
 
-Make sure the repo is cloned and you're working in the root directory of the repo:
+*Instructions for AWS Linux 2023*
 
+1. Provision an EC2 instance. Download the provided `ssh_connect.pem` key and add it to `~/.ssh`.
+2. Point a subdomain of a domain you control to the public IP address.
+3. Add the host to your `~/.ssh/config` file:
 ```
-git clone https://github.com/eriktaubeneck/draft.git
-cd draft
+Host ipa
+    Hostname <subdomain-name-for-helper>
+    User ec2-user
+    IdentityFile ~/.ssh/ssh_connect.pem
 ```
+4. Update the `draft/ansible/inventory.ini` file to only include a single host. (Unless you are running all 4 servers.)
+5. Provision your machine: `ansible-playbook -i ansible/inventory.ini ansible/provision.yaml`
+
+To deploy new changes in draft, run: `ansible-playbook -i ansible/inventory.ini ansible/deploy.yaml`
+
+### Generating TLS certs with Let's Encrypt
+
+You will need a domain name and TLS certificates for the sidecar to properly run over HTTPS. The following instructions assume your domain is `example.com`, please replace with the domain you'd like to use. You will need to create two subdomains, `sidecar.example.com` and `helper.example.com`. (Note, you could also use a subdomain as your base domain, e.g., `test.example.com` with two subdomains of that: `sidecar.test.example.com` and `helper.test.example.com`.)
+
+1. Set up DNS records for `sidecar.example.com` and `helper.example.com` pointing to a server you control.
+2. Make sure you've installed the requirements above, and are using the virtual environment.
+3. Install `certbot`: `pip install certbot`
+4. `sudo .venv/bin/certbot certonly --standalone -m cert-renewal@example.com -d "sidecar.example.com,helper.example.com"`
+    1. Note that you must point directly to `.venv/bin/certbot` as `sudo` does not operate in the virtualenv.
+5. Accept the [Let's Encrypt terms](https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf).
 
 
-Assuming all requirements are installed, start prerequisites:
+### Make Configuration
+
+For this stage, you'll need to know a few things about the other parties involved:
+1. Their root domain
+2. Their public keys
+3. Everyone's *identity* (e.g., 0, 1, 2, 3)
+
+
+Once you know these:
+1. Make a config directory `mkdir config`
+2. Copy the default network config: `cp local_dev/config/network.toml config/.`
+3. Update that file.
+    1. Replace `helper0.draft.test` and `sidecar0.draft.test` with the respective domains for party with identity=0.
+    2. Repeat for identity= 1, 2, and 3.
+    3. Replace respective certificates with their public keys.
+4. Move your Let's Encrypt key and cert into place: `sudo ln -s /etc/letsencrypt/live/sidecar.example.com/fullchain.pem config/cert.pem` and `sudo ln -s /etc/letsencrypt/live/sidecar.example.com/privkey.pem key.pem`
+5. Generate IPA-specific keys:
+    1. Compile `ipa` with `cargo build --bin helper --features="web-app real-world-infra compact-gate stall-detection multi-threading" --no-default-features --release`
+    2. Make the keys with `target/release/helper keygen --name localhost --tls-key h1.key --tls-cert h1.pem --mk-public-key h1_mk.pub --mk-private-key h1_mk.key` (replace h1 with for each helper)
+    3. Add the public keys content into `network.toml`
+    4. Add the public keys to `config/pub` (all helpers need all helper public keys).
+    4. For each helper, put their private keys in `config`.
+
+
+### Run draft
 
 ```
-colima start
-supabase start --workdir server
+draft start-helper-sidecar --identity <identity> --root_domain example.com --config_path config
 ```
 
-Start `draft` for local dev:
+This will start the sidecar in the background. To confirm, visit `example.com/status`.
+
+
+## Local Dev
+
+`draft` provides a fully functional local development setup to work on both the frontend web interface and the sidecar.
+
+### Running local development
+
+If `draft` and the other prerequisites are already installed, run:
 ```
 draft start-local-dev
 ```
 
-### Requirements
+You can follow the logs with:
+```
+draft follow-local-dev-logs
+```
+
+And you can view the front end at [https://draft.test](https://draft.test).
+
+
+
+### Prerequisites
 
 Requirements:
 1. Python 3.11
@@ -41,7 +102,12 @@ Requirements:
 3. [Supabase CLI](https://supabase.com/docs/guides/cli/getting-started)
 4. Docker
 
-#### macOS install
+#### macOS install prerequisites
+
+```brew install python3```
+```brew install node```
+```brew install supabase/tap/supabase```
+```brew install traefik```
 
 
 **Docker**
@@ -51,73 +117,39 @@ There are multiple options to run Docker locally. One such option is [colima](ht
 ```
 brew install docker
 brew install colima
-colima start
 ln -sf ~/.colima/docker.sock /var/run/docker.sock
 ```
 
 The `ln` at the end is because Supabase requires interacting with the local Docker API. See [this Supabase issue](https://github.com/supabase/cli/issues/153) and [this colima issue.](https://github.com/abiosoft/colima/issues/144) This likely requires `sudo`.
 
+### Installation
 
-**Github App**
+Make sure the repo is cloned, and you're working in the root directory of the repo:
 
-The `draft` web front end uses Github for authentication. In order to login locally, you'll need to create a new application for development. Visit [https://github.com/settings/apps/new](https://github.com/settings/apps/new) to create a new Github app using the following parameters:
-1. *name*: draft-local-dev (recommended, but not required)
-2. *Homepage URL:* http://localhost:54321
-3. *Callback URL:* http://localhost:54321/auth/v1/callback
-4. *Request user authorization (OAuth) during installation:* yes
-5. *Webhook active:* false
-6. *Permissions:* Read-only access to email address
-7. *Where can this GitHub App be installed?:* Only on this account
-
-Once you have created the app, you'll need to create a file `server/.env` and add both the `CLIENT_ID` and a generated `CLIENT_SECRET`.
-
-```
-SUPABASE_AUTH_GITHUB_CLIENT_ID="<CLIENT_ID>"
-SUPABASE_AUTH_GITHUB_SECRET="<CLIENT_SECRET>"
 ```
-
-
-**Supabase CLI**
-
-```
-brew install supabase/tap/supabase
+git clone https://github.com/eriktaubeneck/draft.git
+cd draft
 ```
 
-After installing, run
+**Start colima and supabse:**
 
 ```
+colima start
 supabase start --workdir server
 ```
-
-In the output, you'll find an `ANON_KEY`. Update the `server/.env` file one more time to include two new variables:
+In the output, you'll find an `ANON_KEY`. Create the file `server/.env.development.local` and add:
 
 ```
-NEXT_PUBLIC_SUPABASE_URL="http://localhost:54321"
 NEXT_PUBLIC_SUPABASE_ANON_KEY="<ANON_KEY>"
-NEXT_PUBLIC_SITE_URL="https://draft.test"
-SUPABASE_AUTH_GITHUB_CLIENT_ID="<CLIENT_ID>"
-SUPABASE_AUTH_GITHUB_SECRET="<CLIENT_SECRET>"
 ```
 
-**Traefik**
-
-install traefik
+**Add local draft.test domain to `/etc/hosts`:**
 
 ```
-brew install traefik
+echo "#draft local domains\n127.0.0.1 draft.test\n127.0.0.1 sidecar0.draft.test\n127.0.0.1 sidecar1.draft.test\n127.0.0.1 sidecar2.draft.test\n127.0.0.1 sidecar3.draft.test" | sudo tee -a /etc/hosts
 ```
 
-update /etc/hosts with (requires sudo)
-
-```
-127.0.0.1 draft.test
-127.0.0.1 sidecar0.draft.test
-127.0.0.1 sidecar1.draft.test
-127.0.0.1 sidecar2.draft.test
-127.0.0.1 sidecar3.draft.test
-```
-
-make local certs
+**make local certs**
 
 install mkcert with
 
@@ -136,36 +168,19 @@ If you get a warning about the cert not being installed (i.e., it's the first ti
 mkcert -install
 ```
 
-**Run local dev**
-
-You're now ready to install, run, and develop on `draft`!
-
-To start the local development environment:
-
-```
-draft start-local-dev
-```
-
-(Make sure `draft` is installed, see next section.)
-
 ### Install draft
 
-If needed, clone this repo:
-```
-git clone https://github.com/private-attribution/draft.git
-cd draft
-```
-
-**Install `draft`**
 ```
-python -m virtualenv .venv
+python -m venv .venv
 source .venv/bin/activate
 pip install --editable .
 ```
 
-### IPA specific certs
+## Appendix
 
-We check in self signed certs that are only for local development (and are not secure! They are in a public repo!)
+### IPA-specific certs
+
+We check in self-signed certs that are only for local development (and are not secure! They are in a public repo!)
 
 They will periodically expire. You can regenerate them with a compiled helper binary:
 
@@ -177,70 +192,25 @@ target/release/helper keygen --name helper3.draft.test --tls-key local_dev/confi
 
 The public content will also need to be pasted into `local_dev/config/network.toml` for each helper.
 
-## Deployment
-
-### Requirements
-
-*Instructions for AWS Linux 2023*
-
-1. Provision an EC2 instance. Download the provided `ssh_connect.pem` key and add it to `~/.ssh`.
-2. Point a subdomain of a domain you control to the public IP address.
-3. Add the host to your `~/.ssh/config` file:
-```
-Host ipa
-    Hostname <subdomain-name-for-helper>
-    User ec2-user
-    IdentityFile ~/.ssh/ssh_connect.pem
-```
-4. Update the `draft/ansible/inventory.ini` file to only include a single host. (Unless you are running all 4 servers.)
-5. Provision your machine: `ansible-playbook -i ansible/inventory.ini ansible/provision.yaml`
-
-To deploy new changes in draft, run: `ansible-playbook -i ansible/inventory.ini ansible/deploy.yaml`
-
-### Generating TLS certs with Let's Encrypt
-
-You will need a domain name and TLS certificates for the sidecar to properly run over HTTPS. The following instructions assume your domain is `example.com`, please replace with the domain you'd like to use. You will need to create two sub-domains, `sidecar.example.com` and `helper.example.com`. (Note, you could also use a sub-domain as your base domain, e.g., `test.example.com` with two sub-domains of that: `sidecar.test.example.com` and `helper.test.example.com`.)
-
-1. Set up DNS records for `sidecar.example.com` and `helper.example.com` pointing to a server you control.
-2. Make sure you've installed the requirements above, and are using the virtual environment.
-3. Install `certbot`: `pip install certbot`
-4. `sudo .venv/bin/certbot certonly --standalone -m cert-renewal@example.com -d "sidecar.example.com,helper.example.com"`
-    1. Note that you must point directly to `.venv/bin/certbot` as `sudo` does not operate in the virtualenv.
-5. Accept the [Let's Encrypt terms](https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf).
-
-
-### Make Configuration
-
-For this stage, you'll need to know a few things about the other parties involved:
-1. Their root domain
-2. Their public keys
-3. Everyone's *identity* (e.g., 0, 1, 2, 3)
-
-
-One you know these:
-1. Make a config directory `mkdir config`
-2. Copy the default network config: `cp local_dev/config/network.toml config/.`
-3. Update that file.
-    1. Replace `helper0.draft.test` and `sidecar0.draft.test` with the respective domains for party with identity=0.
-    2. Repeat for identity= 1, 2, and 3.
-    3. Replace respective certificates with their public keys.
-4. Move your Let's Encrypt key and cert into place: `sudo ln -s /etc/letsencrypt/live/sidecar.example.com/fullchain.pem config/cert.pem` and `sudo ln -s /etc/letsencrypt/live/sidecar.example.com/privkey.pem key.pem`
-5. Generate IPA specific keys:
-    1. Compile `ipa` with `cargo build --bin helper --features="web-app real-world-infra compact-gate stall-detection multi-threading" --no-default-features --release`
-    2. Make the keys with `target/release/helper keygen --name localhost --tls-key h1.key --tls-cert h1.pem --mk-public-key h1_mk.pub --mk-private-key h1_mk.key` (replace h1 with for each helper)
-    3. Add the public keys content into `network.toml`
-    4. Add the public keys to `config/pub` (all helpers need all helper public keys).
-    4. For each helper, put their private keys in `config`.
+### Local Github Authentication
 
+By default, local authentication is turned off (technically, you're automatically logged in as a demo user.) If you want to test Github authentication locally, you'll need to create a new application for development. Visit [https://github.com/settings/apps/new](https://github.com/settings/apps/new) to create a new Github app using the following parameters:
+1. *name*: draft-local-dev (recommended, but not required)
+2. *Homepage URL:* http://localhost:54321
+3. *Callback URL:* http://localhost:54321/auth/v1/callback
+4. *Request user authorization (OAuth) during installation:* yes
+5. *Webhook active:* false
+6. *Permissions:* Read-only access to email address
+7. *Where can this GitHub App be installed?:* Only on this account
 
-### Run draft
+Once you have created the app, you'll need to update `server/.env.development.local` to include both the `CLIENT_ID` and a generated `CLIENT_SECRET`, and set the `BYPASS_AUTH` flag.
 
 ```
-draft start-helper-sidecar --identity <identity> --root_domain example.com --config_path config
+SUPABASE_AUTH_GITHUB_CLIENT_ID="<CLIENT_ID>"
+SUPABASE_AUTH_GITHUB_SECRET="<CLIENT_SECRET>"
+BYPASS_AUTH=false
 ```
 
-This will start the sidecar in the background. To confirm, visit `example.com/status`.
-
 
 
 # Credit
diff --git a/server/.env.development b/server/.env.development
new file mode 100644
index 0000000..f4f24ee
--- /dev/null
+++ b/server/.env.development
@@ -0,0 +1,13 @@
+# DO NOT ADD SECRETS TO THIS FILE. This is a good place for defaults.
+# If you want to add secrets use `.env.development.local` instead.
+
+# for local dev, we turn off auth, unless specifically working on auth
+BYPASS_AUTH=true
+DUMMY_EMAIL="demo@draft.test"
+DUMMY_PASSWORD="password"
+SUPABASE_AUTH_GITHUB_CLIENT_ID="foo"
+SUPABASE_AUTH_GITHUB_SECRET="bar"
+
+# default supabase variables
+NEXT_PUBLIC_SUPABASE_URL="http://localhost:54321"
+NEXT_PUBLIC_SITE_URL="https://draft.test"
diff --git a/server/middleware.ts b/server/middleware.ts
index 4fecfbd..ae4e880 100644
--- a/server/middleware.ts
+++ b/server/middleware.ts
@@ -54,6 +54,27 @@ export async function middleware(request: NextRequest) {
     },
   );
 
+  if (process.env.NODE_ENV === "development" && process.env.BYPASS_AUTH === "true") {
+    const dummyEmail: string = process.env.DUMMY_EMAIL!;
+    const dummyPassword:string = process.env.DUMMY_PASSWORD!;
+    const { data, error: signInError } = await supabase.auth.signInWithPassword({
+      email: dummyEmail,
+      password: dummyPassword,
+    })
+
+    if (signInError) {
+      const { error: signUpError } = await supabase.auth.signUp({
+        email: dummyEmail,
+        password: dummyPassword
+      });
+      if (signUpError) {
+        console.error('Sign-in error:', signInError);
+        console.error('Sign-up error:', signUpError);
+        throw new Error('Failed to handle local development auth bypass.');
+      }
+    }
+    return response
+  }
   const {
     data: { user },
   } = await supabase.auth.getUser();