> For the complete documentation index, see [llms.txt](https://docs.telys.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.telys.ai/self-hosting/auth-and-network.md).

# Auth & network

A Telys server has a small, explicit security model: the transport decides trust, an access token gates TCP, an optional license gate blocks boot, and the wire protocol is a length-prefixed JSON frame with a hard size cap. There are no accounts, roles, or per-collection permissions, and the server makes no outbound network calls.

## Transport decides trust

The server authorizes connections by *how* they arrive, not by a per-user identity.

{% tabs %}
{% tab title="Unix socket — trusted" icon="plug" %}
Created with `0600` permissions (owner read/write only) and treated as **trusted**. Any local process that can open the socket file is authorized; no token is required or checked.

Trust here is filesystem trust: the socket-file permissions are the access control. Keep the socket in a directory only trusted users can reach.

```bash
telys serve --path ./memory --socket /run/telys/telys.sock
```

{% endtab %}

{% tab title="TCP — token required" icon="network-wired" %}
Reachable from other hosts, so it is **never** anonymous. Supply an access token when starting the server; a TCP server refuses connections without one, and a client that omits or mismatches the token is rejected.

```bash
telys serve --path ./memory --host 0.0.0.0 --port 9099 \
  --access-token "$TELYS_ACCESS_TOKEN"
```

Bind TCP to a private interface behind a firewall — the token authenticates the caller, it does not encrypt the link.
{% endtab %}
{% endtabs %}

## The token handshake

A client given a token sends an **authentication handshake as its first message**, before any other request. The server compares the presented token against the configured one and either continues or drops the connection.

```python
from telys.client import connect

# token is sent as the first frame, then normal calls follow
with connect("tcp://memory.internal:9099", token="$TELYS_ACCESS_TOKEN") as client:
    print(client.ping())
```

{% hint style="info" %}
The server compares tokens in **constant time**, so a wrong token takes the same time to reject regardless of matching prefix length — closing the timing side-channel a naive equality would open. Generate a long, random token with `secrets.token_urlsafe(32)`, not a memorable phrase.
{% endhint %}

The token is bearer-style — possession is authorization. Treat it like a password: pass it through `$TELYS_ACCESS_TOKEN` rather than a flag to keep it out of shell history and the process list, and rotate it by restarting the server with a new value.

## The license gate

Independently of transport auth, a server can require a valid license before it will run. Start it with `--require-license` (or `require_license=True` in `serve()`), optionally with `--license` / `$TELYS_LICENSE`:

```bash
telys serve --path ./memory --socket /tmp/telys.sock --require-license
```

On boot the server verifies a `products.telys` **version-2** license **entirely offline** — signature and claims are checked against an embedded public key, with no call to a license server. If verification fails, the server refuses to start; there is no unlicensed fallback. This enforces the `telys_team` self-host tier. The verification rules (issuer, audience, expiry, product claims) are in [Offline licenses & verification](/licensing/offline-licenses.md).

## The wire protocol

Client and server speak a small framed protocol over the socket:

* Each message is a **4-byte length prefix** followed by a **JSON** payload of that many bytes.
* The maximum frame size (`MAX_FRAME`) is **256 MiB**. A frame that declares or exceeds this size is rejected rather than buffered, bounding server memory.

```
+------------------+-------------------------------+
| 4-byte length N  | JSON payload (N bytes)         |
+------------------+-------------------------------+
                    N <= 256 MiB (MAX_FRAME)
```

Framing is identical on both transports; only the socket underneath differs. Requests name a method and its arguments; responses carry the result or an error. Vectors and metadata cross the wire as JSON — batch large ingests into reasonable frames and remember the 256 MiB per-frame ceiling.

## What never happens

{% hint style="success" %}
The server makes **no outbound network calls** of any kind. It listens on the one socket you configured, verifies licenses offline against an embedded key, and reads and writes the store directory — nothing else touches the network. See [What leaves the machine](/security/what-leaves-the-machine.md) and [On-device & offline-first](/understand-telys/on-device-offline.md).
{% endhint %}

* No telemetry, phone-home, or usage reporting from the server.
* No online license check — verification is local and offline.
* No per-user identity or role system — trust is transport plus one shared token.

## Next steps

* Next: [Deployment notes](/self-hosting/deployment.md) — run the server behind a private network, under a supervisor, with backups.
* [Security overview](/security/overview.md) — how Telys's trust anchors fit together.
* [Connect with RemoteTelys](/self-hosting/connecting-remote.md) — the client side of this protocol.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.telys.ai/self-hosting/auth-and-network.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
