Skip to content

Commit

Permalink
Optional local auth (#34)
Browse files Browse the repository at this point in the history
* make user auth optional for local dev

* grammer fixes in README

* more grammer fixes in README

* [failsafe] block demo user outside development if added to prod database by mistake

* create dummy user on the fly in development mode, remove from seed.sql

* clean up error handling for local auth bypass

* readme typo

* readme typo
  • Loading branch information
eriktaubeneck authored Jun 10, 2024
1 parent 9ca2f1f commit 72af906
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 140 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ IGNORE-ME*
.draft

# local env files
.env*
.env*.local

# local certs
local_dev/config/cert.pem
Expand Down
248 changes: 109 additions & 139 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,113 @@
# 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 [email protected] -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
2. Node 20
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**
Expand All @@ -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

Expand All @@ -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:

Expand All @@ -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 [email protected] -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
Expand Down
13 changes: 13 additions & 0 deletions server/.env.development
Original file line number Diff line number Diff line change
@@ -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="[email protected]"
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"
21 changes: 21 additions & 0 deletions server/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit 72af906

Please sign in to comment.