# Security

## Your account

**Turn on two-factor authentication**: it's recommended for everyone, and for an organization's owners especially. Signing in then takes a six-digit code from an authenticator app (1Password, Apple Passwords, Google Authenticator, Authy and others) as well as your password, so a password that leaks isn't enough to get in.

- Turn it on under **Your account → Two-factor authentication**: scan the QR code, type the code the app shows and your password.
- You get ten **recovery codes**, shown once. Each signs you in once instead of a code from the app, for when your phone is lost. Keep them in a password manager or printed; make new ones there when they run low.
- A code works once, and wrong codes count as failed sign-ins: after 10 in a quarter of an hour, the address waits.
- Choosing a new password with a link from the email leaves it on: someone who can read your mailbox still needs your phone.
- Turning it off, or making new recovery codes, asks for your password and a code again. Each change is confirmed by email.
- The command-line tool and coding agents are let in from a browser you're signed in to, so they're covered by it too.

**Signing in with GitHub or Google** uses the address they have confirmed, so there's no confirmation email; an account with the same address is linked, and two-factor authentication still asks for its code. An account made this way has no password until you choose one with "Forgot your password?".

Also under Your account: every place you're signed in, each with a way to sign it out.

## Your data

- **Variables, secrets and webhook URLs** are encrypted at rest. Secret values are never shown again after saving, to people or agents.
- **Server and agent tokens** are stored only as hashes; they're shown once.
- **Uploaded code** is kept for the newest few deploys of each service, then deleted.

## Your servers

- A server connects out to Alf over HTTPS; nothing needs to reach it for visitors.
- Your apps' traffic reaches the server over that connection. Apps never see each other's traffic.
- Between servers, project networks run through an encrypted WireGuard tunnel. Every project has its own network with its own addresses: other projects, yours or anyone else's, can't reach it, on the same server or across servers.
- A [device in a project's network](/docs/network-access) (`alf connect`) is let into that project's network on each of its servers and nothing else: not other projects, not the servers themselves. Its private key never leaves it; it's listed in the project's settings, and revoked there in seconds, or when its owner leaves the organization.
- On the shared servers, containers of different organizations run side by side on one machine. Every container runs in a virtual machine of its own ([Kata Containers](https://katacontainers.io)), with its own Linux kernel and the processor's hardware virtualization between it and the machine, so a bug in a kernel isn't a way out of the container: apps, databases, computers, the terminals opened in them and every step of a build, with no exceptions. A server that can't start one runs nothing. Every container is also created without the powers nothing ordinary needs — raw sockets above all, which would let it forge ARP and DNS replies to its neighbours — and with a limit on memory, CPU and processes. See [What a container gets](/docs/containers).
- An organization that would rather have machines to itself can have [private servers](/docs/servers#private-servers). That is the only arrangement in which nobody else's code runs on your hardware, and it is the right one if you need to be able to say so.

## Agents

- Agents act within one organization, with the access you gave them, and can be limited to a project.
- They can't delete anything but previews, can't read secret values, and every change is logged.
- Approvals, limits and revocation are on the Agents page. See [Approvals, limits and service accounts](/docs/agent-safety).

## Webhooks

Nothing connects to your code host: CI pushes code here with a deploy token you can limit to one project and revoke. Notification webhooks carry a signature you can check. See [Notifications](/docs/notifications).
