# Security model

> How Team Cloud's end-to-end encryption works for a team, who holds which keys, how every Mac checks the server, who enforces each control, and what each kind of attacker can and can't do.

Source: https://docs.subcloak.com/cloak-proxy/team/security-model/

Added in Cloak Proxy 0.7.0.

{/* L9 draft. Sources: PLAN 1, 3.4, 5, 9.2, 12.2; protocol-team.md v1 (T3–T15, T20). Plain-words version of the threat model, as LAUNCH 5.2 asks. */}

Team Cloud extends [Personal Cloud's design](https://docs.subcloak.com/cloak-proxy/cloud/security/) to a team: the same encryption, signatures, code comparison, checkpoints and Recovery Kit, with people and roles added. Subcloak's server stores the team's data without being able to read it (unless an admin turns on automatic approval after SSO, below), and members' Macs don't take the server's word for who is in the team or who may change what.

## The short version

{/* PLAN 1, 5 */}

- **Members' Macs lock everything before it leaves them.** The keys are on members' Macs, on the CI tokens admins create (for the spaces they're given) and on the Team Recovery Kit.
- **The team's member list is signed.** Who's in the team, their roles and their Macs are a signed, chained record that every Mac checks. The server can't add a person, a Mac or a role, unless an admin turns on automatic approval after SSO, which lets the server and your identity provider admit a Mac for an existing member.
- **Writes are checked twice.** The server refuses writes a person isn't allowed to make, and every Mac skips any that get through anyway.
- **Reads are limited by keys.** A Mac can only decrypt what it was given keys for.
- **The console holds no keys.** Anything that needs one is done by an admin's Mac.
- **Two features are deliberately not end-to-end:** monitors and hosted mocks (\*), which run on our servers from copies a person publishes after a warning.

## The keys

{/* PLAN 5; T3, T6, T7, T8, T12, T13 */}

| Key | What it's for | Who holds it |
|---|---|---|
| **Each Mac's team keys** | A signing key ("this came from Alex's MacBook Pro") and a sealing key. One pair per team, separate from Personal Cloud's | That Mac's Keychain |
| **The team key** | Encrypts the keys of every open space. Replaced whenever someone is removed or the kit is used | Every member's Mac (sealed to each), the kit |
| **Space keys** | Encrypt a restricted space, such as a vault folder. Handed out by grants signed by a Mac already listed in the space, sealed to each listed person's Macs | Listed members' Macs, the kit |
| **The Team Recovery Kit** | Recovers the team when every admin's Mac is lost | Printed, kept by the company |
| **The team inbox key** | CI uploads are sealed to it, so a CI token can add recordings without being able to read the library | Every member's Mac |
| **A CI token's keys** | Read the spaces granted to that token | The token (shown once, kept in your CI's secrets) |
| **A pair session key** | Encrypts one pair debugging session. Every frame is also signed by the Mac that sent it | The host and the invited viewers' Macs |

The algorithms are Personal Cloud's: HPKE (RFC 9180, X25519, HKDF-SHA256, AES-256-GCM) for sealing, AES-256-GCM for content, Ed25519 for signatures, HKDF-SHA256 and SHA-256. Each kind of signed record is domain-separated, so a team signature can never be used as a personal one or the reverse. Nothing here is new cryptography. {/* T base rule, PLAN 12.3 item 1 */}

## How Macs check the server

{/* PLAN 5, 3.4; T4, T6.1, T7.2, T9, T11 */}

- **The member list** is a chain of signed entries. Only an admin's Mac can add a person or change a role; a member's own Mac can add that member's further Macs; the kit can make its holder an admin. A Mac refuses any entry signed by someone who wasn't allowed to make it.
- **Every item** is signed by the Mac that wrote it, and applied only if that Mac's owner had the role to write it at that point in the history.
- **Every space's access list** is signed, chained and checked from its first version. Only a manager, or an admin in an open space, can widen it.
- **A space key** is accepted only from a Mac listed in that space, for the right recipient, matching the key's commitment, so the server can't make a Mac use a key it chose.
- **Approvals** of protected changes are checked on every Mac: a manager's signature, no self-approval, and the exact change.
- **Checkpoints.** Macs regularly sign how far they've read the history. If the server shows two Macs different histories, or withholds changes, the checkpoints disagree and Macs raise a warning.

## Who enforces what

{/* PLAN 3.4 */}

The table is the same as on [Spaces, roles and permissions](https://docs.subcloak.com/cloak-proxy/team/spaces-and-roles/#who-enforces-what). In short: reading is enforced by keys; writing, roles and membership by signatures and by the server; billing, seats, SSO-required sign-in and SCIM by the server; and each [policy](https://docs.subcloak.com/cloak-proxy/team/policies/) says who enforces it.

## What each attacker can and can't do

{/* PLAN 12.2, in plain words */}

| If this is compromised… | They could | They couldn't | What's left |
|---|---|---|---|
| **Subcloak's server** | See metadata and the server-side features\*; withhold, delay or reorder changes; refuse service; serve a malicious console page | Read spaces, the vault, comments, the library or pair traffic (unless automatic approval is on: then, with your IdP, it can admit a Mac as an existing member, which reads what that member can); forge members, roles, Macs, grants, approvals or access lists; turn on automatic approval; add a Mac without a person comparing a code (unless automatic approval is on) | Withholding is detected, not prevented. With automatic approval on, the server and your IdP decide joins |
| **The network** | Nothing beyond breaking connections | Change requests: each is signed by the Mac and bound to the server | — |
| **A removed member** | Keep what they downloaded, and open it with the old keys they had | Fetch anything after removal; decrypt anything written after the key change | Old copies can't be taken back; rotate vault secrets at their source |
| **A member** | Read their spaces, write where they're an editor, propose, comment, and leak what they can read | Read restricted spaces they're not in; approve their own proposal; change roles or access lists (unless a manager); add people | An insider can leak what they can read |
| **An admin** | Add or remove people, approve Macs, read every open space | Read restricted spaces they're not in; hide that they acted | Admins are trusted with membership: one could add an accomplice, who would get only the open spaces |
| **A member's stolen Mac** | Act as that member until removed | Survive removal | Remove the person in the console as soon as you know |
| **An owner's console account** | Change billing, remove members, change policies, add billing managers, revoke CI tokens, export the audit log | Read team data; add a person or a Mac (unless automatic approval after SSO is on: then, by pointing SSO at an identity provider it controls, it can admit a Mac as an existing member); make someone an admin (needs an admin's Mac) | Disruption and metadata. Passkeys, confirmation for sensitive actions and security emails reduce it |
| **Your IdP** | Sign in as any member, to the console (with that member's team role only) and the app | Give a Mac the team's keys, unless automatic approval is on; act as the owner or a billing manager; add a passkey to anyone's account | With automatic approval on, admit a Mac with that member's access. A new or changed IdP signs in nobody but the admin who tested it until the owner confirms it |
| **A leaked CI token** | Read the rule sets, mock sets and workspaces an admin gave it; upload recordings to an open library named by its id | Read the vault, the library, findings or agents; read anything not granted; change the team | Until revoked |
| **Someone abusing hosted mocks or monitors** | Serve JSON, text or images at an unguessable URL (paid teams only); call a public site every 5 minutes | Serve web pages or scripts; reach private addresses or our own hosts; exceed the limits | Abuse reports and takedown |

## The console

{/* PLAN 9.2 */}

- Sign-in by email code, passkey or SSO. Sessions last up to 12 hours idle and 7 days in all, and are listed and revocable under **Your account**.
- Sensitive actions ask you to confirm with a passkey or a fresh email code: removing a member, changing seats, the interval or cancelling, adding or removing console users, changing SSO, **Require SSO** or the SCIM token, adding, verifying or removing a domain, loosening a policy or changing library retention, opening the billing portal, exporting the audit log, deleting the team, and adding or removing a passkey.
- Security emails go to you on a sign-in from a new country, a passkey added, SSO changed or a deletion requested.
- A sign-in through SSO acts in your team only, with the person's team role. It never makes anyone the owner or a billing manager, and it can't add or remove passkeys.
- The console's pages are served with a strict Content Security Policy and never render your data as HTML.

## Limits

{/* PLAN 1.1 published weaknesses; T5.5 v1 residual risk */}

- **Metadata is visible.** See [What Subcloak can and can't see](https://docs.subcloak.com/cloak-proxy/team/what-subcloak-can-see/).
- **The server can withhold or delay changes.** Macs detect it with checkpoints but can't force delivery.
- **Removed members keep what they downloaded.**
- **Automatic approval after SSO, if on,** makes our server and your IdP part of who joins.
- **Policies enforced on each Mac** can be bypassed by a modified app.
- **The console is served by Subcloak.** A compromised server could serve a malicious console page. It still couldn't read team data or add a Mac, because the console never holds keys, unless an admin turned on automatic approval after SSO.
- **Recovery with the kit trusts the history the server shows** until the recovering Mac checks it against other members' checkpoints and the Security code. See [Recovery](https://docs.subcloak.com/cloak-proxy/team/recovery-and-start-over/#recover-with-the-team-recovery-kit).
- **Your Mac's own security matters.** Malware running as you can read what Cloak Proxy can.

## Report a security problem

Email `hello@subcloak.com`. See Subcloak's [security and disclosure policy](https://subcloak.com/security). Test only your own team.

## Related

  - [What Subcloak can and can't see](https://docs.subcloak.com/cloak-proxy/team/what-subcloak-can-see/): The full list, with retention.
  - [Personal Cloud security](https://docs.subcloak.com/cloak-proxy/cloud/security/): The shared foundations, in detail.
  - [Team keys and the Recovery Kit](https://docs.subcloak.com/cloak-proxy/team/team-keys/): Keys and the Team Security code.
