# Access controls

> Decide which people and devices can reach each other, with rules by group, tag, service or app, and tests that run before you save.

Access controls are your workspace's **policy**: a list of rules saying who can reach what. You edit them on the dashboard's **Access controls** page.

> [!IMPORTANT]
> Until you save a policy, every device in your workspace can reach every other. Once you save one, **only what the rules allow gets through** and everything else is blocked. A policy with no rules blocks all traffic between machines. Write your rules, and a few tests, before you save.

## How rules work

Each rule says: these **sources** can reach these **destinations**, on this **protocol** and these **ports**. Rules only ever allow; if no rule allows a connection, it's blocked.

```json
{
  "src": ["group:eng"],
  "dst": ["tag:prod"],
  "proto": "tcp",
  "ports": ["22", "5432"],
  "note": "Engineers manage production"
}
```

## Selectors

| Selector | Means | Use in |
|---|---|---|
| `*` | Every machine | Sources and destinations |
| `group:<name>` | Every machine owned by a member of the group | Sources and destinations |
| `user:<email>` | Every machine that person owns | Sources and destinations |
| `tag:<name>` | Machines that joined with a key carrying that tag | Sources and destinations |
| `machine:<id>` | One machine, by its ID | Sources and destinations |
| `svc:<name>` | A [service](/features/services) | Destinations |
| `app:<app ID>` | An [app](/features/app-connectors), through its connectors | Destinations |
| `192.168.1.0/24` | A [subnet route](/features/subnet-routes) | Destinations |
| `autogroup:internet` | Internet traffic through an [exit node](/features/exit-nodes) | Destinations |

**Protocols:** `any`, `tcp`, `udp` or `icmp`.
**Ports:** one port (`22`), a range (`8000-8100`), or `*` for all. Ports are ignored for `icmp`.

## The policy

A policy has four parts:

```json
{
  "groups": {
    "group:eng": ["priya@acme.com", "jonas@acme.com"],
    "group:sales": ["sam@acme.com"]
  },
  "rules": [
    { "src": ["group:eng"], "dst": ["tag:prod"], "proto": "tcp", "ports": ["22", "5432"] },
    { "src": ["group:sales"], "dst": ["svc:crm"], "proto": "tcp", "ports": ["443"] },
    { "src": ["*"], "dst": ["svc:wiki"], "proto": "tcp", "ports": ["443"] }
  ],
  "ssh": [
    { "src": ["group:eng"], "dst": ["tag:prod"] }
  ],
  "tests": [
    { "src": "priya@acme.com", "accept": ["tag:prod:22"], "deny": [] },
    { "src": "sam@acme.com", "accept": ["svc:crm:443"], "deny": ["tag:prod:22"] }
  ]
}
```

### Groups

Named lists of people's emails, written in lowercase. Use them as `group:<name>` in rules.

### SSH rules

SSH rules always mean **TCP port 22**, to **machines** only (not services or apps). Keeping them separate makes it easy to see who can log in where.

### Tests

A test names a source and lists what it **must** reach (`accept`) and what it **must not** reach (`deny`), written as `<selector>:<port>` over TCP, like `tag:prod:22`. A policy only saves if every test passes, so a change can't silently break access.

## Where rules are enforced

Each device enforces the rules for the traffic it **receives**:

- It lets in only what the rules allow, plus replies to connections it started itself (replies are remembered for 5 minutes of quiet).
- What a device sends out is never blocked.
- A rule that can't be applied is skipped, never treated as allow-all.

> [!WARNING]
> Devices enforce access rules from app version **0.3** onwards. Keep every device up to date so all of them enforce your policy.

## Limits

| What | Limit |
|---|---|
| Rules (including SSH rules) | 200 |
| Groups | 100, with up to 500 members each |
| Tests | 100, with up to 50 targets each |
| Sources and destinations per rule | 1 to 50 |
| Notes | 200 characters, one line |
| Tag names | `tag:` + letter or digit, then up to 62 of `A-Z a-z 0-9 _ . -` |
| Group names | `group:` + lowercase letter or digit, then up to 62 of `a-z 0-9 _ . -` |

## History

Every saved change is recorded in the [audit log](/manage/logs#audit-log), with who made it.
