> ## Documentation Index
> Fetch the complete documentation index at: https://docs.neochamber.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Security model

> Credentials, sessions, and why there are no shared secrets anywhere in the platform.

## Accounts and sessions

* Passwords are **argon2id-hashed**, minimum **12 characters**.
* Sessions are **opaque 30-day tokens**, stored only as hashes. Cookies are
  httpOnly and secure.
* Changing your password signs out every **other** session and keeps the one
  you are using.
* Changing your email requires your current password, and the new address
  becomes your login immediately.

## No shared credentials, anywhere

Every agent, operator, and customer holds **its own revocable identity**:

* Each **node** holds its own credential, issued at enrollment — not a copy of
  the enrollment token that installed it.
* Each **enrollment token** is stored only as a hash and revealed exactly once,
  at creation.
* Each **invite** and **reset code** is single-use and time-boxed.

This is what makes revocation surgical. Revoking an enrollment token stops it
enrolling new machines immediately and leaves every already-installed server
running. Deleting a teammate's account kills their sessions, then the account,
then every invite and reset code it handed out — and the servers they installed
keep running, because those nodes never held their credential.

In **sovereign** deployments there are no long-lived cloud keys either: the
console reaches your cloud through short-lived, identity-federated credentials.

## No email, by design

The platform **sends no email at all**. There is no "email me a reset link"
flow, because that flow is an account-takeover path that depends on a mail
provider you do not control.

Locked out? Your provider (or, for operators, NeoChamber) issues a **one-time
reset code**: single-use, expires in an hour, redeemed at `/reset` with your new
password. Your account, tenant, and history are untouched; every other session
of yours is signed out.

## Invite codes

| Property   | Value                                 |
| ---------- | ------------------------------------- |
| Uses       | Single-use                            |
| Validity   | 14 days                               |
| Visibility | Shown exactly once, at creation       |
| Scope      | Names the operator or tenant it joins |

Because an invite names the boundary it joins, a colleague can never land in the
wrong datacenter, and a customer can never land in the wrong tenant.

Every invite minted and redeemed is recorded.

## Uploads are checked by their bytes

For profile photos and console logos, the file's **actual bytes** decide what it
is — never its filename and never what the browser declares. A renamed file is
refused rather than trusted.

**SVG is refused deliberately.** An SVG is a document that can carry script, and
your logo is served back from your own console's origin. Export a PNG at 2×
instead.

## What is audited

The audit trail covers the **account-takeover paths**: invite mint and
redemption, signup-code mint/rotate/redeem, reset codes from both consoles, and
account deletions. Each row records actor, action, target, and IP.

<Note>
  Being precise rather than flattering: tenant, node, token-rotation, branding,
  and profile changes are **not** in the audit log yet. The console panel says so
  too. This is a known and documented boundary, not an oversight we are hoping you
  do not notice.
</Note>
