# Network access

Your laptop, or any other machine, can join one project's private network: its services — the private ones included, like a database with no address of its own — are then reachable from it as if it were one of them. It's how you point a database tool at production's Postgres, run a script against a private API, or debug something that only answers inside the project.

```bash
alf connect shop
```

```text
In shop's network as 10.88.128.1. Its services, here:

SERVICE   ON THIS MACHINE   IN SHOP
db        localhost:5432    10.128.4.2:5432
web       localhost:80      10.128.4.3:80

✓ Connected to fsn-1.
Ctrl-C to leave. The device stays registered for next time.
```

Each service opens on `localhost`, on the port it listens on (or a free one, if that's taken), until you press Ctrl-C. `psql postgres://app:…@localhost:5432/app` then talks to the project's database. The list has the rest of the project too: a computer (which has no one port to open: name one, or use `--all`), and static sites and buckets at their public addresses, since they aren't anything to tunnel to.

## Every port, at each service's own address

```bash
alf connect shop --all
```

```text
SERVICE    ADDRESS                     INSIDE
postgres   postgres.shop.internal      10.128.4.4 (listens on 5432)
web        web.shop.internal           10.96.8.2 (listens on 8080)
computer   computer.shop.internal      10.128.4.5
```

With `--all` the project's network becomes a network interface of your machine while it runs: every port of every service, at its own address, for any program — `psql -h postgres.shop.internal`, a browser at `http://web.shop.internal:8080`, `ssh root@computer.shop.internal`. The names go into `/etc/hosts` and come out again when you leave. Making an interface needs root, so it asks for `sudo`; only that part runs as root, and your sign-in and the device's key stay yours.

A [computer](/docs/computer-access#every-port-from-your-laptop) has an SSH server already: `ssh dev@computer.shop.internal`, with your public key in its `~/.ssh/authorized_keys` (or use `alf ssh`, which needs no network access at all).

## What happens

The first time, the [command-line tool](/docs/cli) makes a [WireGuard](https://www.wireguard.com) key on your machine and registers the **device** with the project. Only the public half of the key is sent; the private half never leaves the machine. The device gets an address of its own in the project's network, and every server the project runs on adds it as a peer.

WireGuard runs inside the tool, with a network stack of its own: no `sudo`, no app, no kernel module, and nothing else on your machine sees the project's network. Only what `connect` opens on `localhost` reaches it. The connection goes out over UDP to the servers' port 51820, which most networks let through; it's kept alive every 25 seconds, so it works from behind NAT and over Wi-Fi that changes.

```diagram network-access
On your laptop, programs like psql or a browser connect to localhost:5432, where alf connect listens. The tool runs WireGuard inside itself, with its own network stack: no app and no kernel module. It talks over UDP 51820, kept alive every 25 seconds, to each server project shop runs on. There the device is in shop's network: db at 10.128.4.2:5432, and web, woken by the first connection if it's asleep. What it sends to other projects or to the server itself is dropped. The device's key is made on the laptop and only its public half is sent; every server the project runs on adds the device as a peer until its time is up or it's revoked.
```

## What a device can reach

- **This project's services, and nothing else.** Each server lets a device into the project's network on that server, and drops everything else it sends: other projects (yours or anyone's on a shared server), and the server itself — its SSH, its own ports, everything.
- **By their addresses inside the project**, the way the project's services reach each other. Their public addresses work as always.
- **A service that sleeps** is woken by the first connection, the way the project's own services wake it: a device reaches it through its front address, which the server holds while it's asleep. The first connection takes as long as the service takes to start.

## Pick services and ports

```bash
alf connect shop db               # only db, on the port it listens on
alf connect shop db=15432         # db on localhost:15432
alf connect shop worker:9000      # a port the service didn't say it listens on
```

## How long a device works

**30 days** from when it's made, unless you say otherwise:

```bash
alf connect shop --days 7
alf connect shop --forever        # until it's revoked
```

In the project's **Settings → Network access**, **Keep it…** changes that at any time: 7, 30 or 90 days from now, or for good. When a device's time is up it stops working, and `connect` makes a new one the next time.

## Seeing and revoking devices

The project's **Settings → Network access** lists every device: whose it is, its address, whether it's connected now — to which servers, and from which address — or when it last was, and until when it works. Devices also show on the project's canvas, under the servers they're connected to.

**Revoke** takes a device off the network at once, wherever it is: every server drops it within seconds. Revoked and expired devices stay in the list (**Show revoked and expired ones too**), so it still says who had access, and until when.

- `alf disconnect shop` revokes this machine's device and forgets its key.
- `alf devices` lists the devices in all your projects; `alf devices revoke <id>` revokes one.
- **Someone who leaves the organization** takes no access with them: their devices are revoked when they're removed.

Joining a device is an owner's or an admin's to do, as opening a shell is. Its owner, or an admin, can revoke it.

## On another machine

```bash
alf connect shop --config > shop.conf
```

prints a WireGuard configuration for the device instead of connecting: for the WireGuard app, or `wg-quick up ./shop.conf` on a server of your own. With it, the whole of the project's network is routed (not only `localhost` ports), and the services' addresses are listed at the top of the file. **It has the device's private key in it:** keep it to yourself, and revoke the device if it gets out.

## Good to know

- A device is one machine in one project. Another project, another device: `alf connect blog`.
- A server too old for devices doesn't get them (servers update themselves, usually within a day): until then, what runs on it can't be reached, and `connect` says so.
- If `connect` says **No answer yet**, the network you're on doesn't let UDP out to port 51820. Another network (a phone's hotspot, say) usually does.
