> 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/understand-telys/signed-runtime-trust.md).

# Signed runtime & trust

The `telys` SDK is pure Python, but the engine it drives — the native runtime and the embedding kernel — ships as a **signed bundle**. Before that bundle is activated, the SDK verifies three things: a release manifest signed by Telys's release key, every on-disk artifact matching the hash the manifest promises, and a valid offline license for this machine. Any check fails and the runtime does not load. This page describes that chain and the API you run yourself.

## What ships signed

A verified install lands under `$TELYS_HOME/runtime/<platform>/` (for example `runtime/macos-arm64/`) and contains the runtime, the kernel, the signed manifest, and the license:

| File                        | Role                                                       |
| --------------------------- | ---------------------------------------------------------- |
| `libty_runtime.<ext>`       | the native runtime (`.dylib` / `.so` / `.dll`)             |
| `libame_kernel.<ext>`       | the embedding kernel                                       |
| `telys_manifest.json`       | the release manifest (versions + expected artifact hashes) |
| `telys_manifest.sig`        | RS256 / PKCS#1 v1.5 signature over the manifest            |
| `license.jwt`               | the offline license token                                  |
| `installed.json`, `pysite/` | install metadata and the runtime's Python site directory   |

## The verification chain

The SDK walks three anchors in order, and every one must pass.

{% stepper %}
{% step %}

#### Verify the release manifest signature

`verify_manifest(manifest_bytes, signature, pubkey=None)` checks `telys_manifest.sig` against `telys_manifest.json` with RS256 / PKCS#1 v1.5 and SHA-256, defaulting to the embedded release public key, and returns the trusted manifest as a dict. A tampered or unsigned manifest fails here, so nothing downstream is believed.
{% endstep %}

{% step %}

#### Verify every artifact hash

For each artifact the manifest describes, `verify_artifact(path, expected_sha256)` recomputes the file's SHA-256 (via `sha256_file`) and compares it in **constant time** to the value the signed manifest promised. A swapped or corrupted `libty_runtime` / `libame_kernel` is rejected here.
{% endstep %}

{% step %}

#### Verify the offline license

`verify_license(token, pubkey=None, *, now, issuer=None, audience=None, product="telys")` validates `license.jwt` strictly and entirely offline against the embedded license public key: it pins the algorithm to RS256, rejects any `crit` header, checks `iss` / `aud` / `ver == 2` and `exp` plus a grace window, and reads the `products.telys` tier and features. Only then is the runtime activated.
{% endstep %}
{% endstepper %}

## Fail-closed and native-only

A verified install is **native-only**. `load_runtime()` loads the signed native runtime for a native or verified install and never silently downgrades a verified install to the local runtime. If the runtime cannot be imported it raises `RuntimeNotInstalled` rather than degrading — the trust model is fail-closed, so an install that does not verify simply does not run.

Importing the package wires it in: `import telys` prepends the verified install's `pysite/` to `sys.path` (a silent no-op when there is none). `TELYS_RUNTIME` can force `"native"` or `"local"` to override auto-detection.

## The embedded trust anchors

The public keys the SDK trusts are shipped **inside the wheel**, so verification needs no network and no external key server:

* `release_public_key()` → `telys/_keys/telys_release_pub.pem` (verifies the manifest)
* `license_public_key()` → `telys/_keys/telys_license_pub.pem` (verifies the license)

Both require the `cryptography` package (a hard SDK dependency). You can override the keys and license expectations via environment — `TELYS_RELEASE_PUBKEY` / `TELYS_RELEASE_PUBKEY_FILE`, `TELYS_LICENSE_PUBKEY` / `TELYS_LICENSE_PUBKEY_FILE`, `TELYS_LICENSE_ISSUER`, and `TELYS_LICENSE_AUDIENCE` — but the defaults are the production trust anchors.

| Constant                    | Default                            |
| --------------------------- | ---------------------------------- |
| `DEFAULT_LICENSE_ISSUER`    | `https://license.algenta.ai`       |
| `DEFAULT_LICENSE_AUDIENCES` | `telys-runtime`, `algenta-runtime` |
| `SUPPORTED_LICENSE_VER`     | `2`                                |
| `PRODUCT`                   | `telys`                            |

## Verify it yourself

The one-command path runs the whole chain and is the recommended check after any install or upgrade:

```bash
telys runtime verify        # exit 0 when signature + hashes + license all pass
```

{% hint style="warning" %}
There is no standalone `telys verify` command — signature verification is `telys runtime verify` plus the `telys.verify` API below.
{% endhint %}

For scripting or auditing, the same primitives are importable. The manifest bytes, signature, expected hashes, and license token all come from the signed bundle in `$TELYS_HOME/runtime/<platform>/`:

```python
import datetime
from telys.verify import (
    release_public_key,
    license_public_key,
    verify_manifest,
    verify_artifact,
    verify_license,
    sha256_file,
)

# The public keys the SDK trusts (from the embedded PEMs).
release_pub = release_public_key()
license_pub = license_public_key()

# 1. Manifest signature -> trusted manifest dict (RS256 / PKCS1v15 / SHA-256).
manifest = verify_manifest(manifest_bytes, signature)

# 2. Artifact integrity -> raises if a file's SHA-256 does not match.
verify_artifact("libty_runtime.dylib", expected_sha256)   # expected value from the manifest

# 3. Offline license -> claims dict; strict, no network, pins RS256, ver == 2.
now = int(datetime.datetime.now(datetime.timezone.utc).timestamp())  # verify_license wants a Unix int
claims = verify_license(license_jwt, now=now)
print(claims["products"]["telys"])   # tier + features
```

## Next steps

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Security overview</strong></td><td>The whole trust posture, end to end.</td><td><a href="/pages/jLlQKGv5GwnJU5gn4Frl">/pages/jLlQKGv5GwnJU5gn4Frl</a></td></tr><tr><td><strong>Three trust anchors</strong></td><td>Release key, license key, and artifact hashes in depth.</td><td><a href="/pages/IfZ7h0ml3OjlVuNi4tGX">/pages/IfZ7h0ml3OjlVuNi4tGX</a></td></tr><tr><td><strong>Verify the runtime signature</strong></td><td>Run the verification chain step by step.</td><td><a href="/pages/as3JvHboA5RxokqNHpAw">/pages/as3JvHboA5RxokqNHpAw</a></td></tr><tr><td><strong>Verify your install</strong></td><td>Confirm the runtime is installed and trusted.</td><td><a href="/pages/h4z9ZPSmvEnW3qsGotXt">/pages/h4z9ZPSmvEnW3qsGotXt</a></td></tr></tbody></table>


---

# 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/understand-telys/signed-runtime-trust.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.
