> 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/troubleshooting/signature-verification.md).

# Signature verification

Telys is fail-closed: a verified install runs **native-only** and refuses a runtime it can't trust. Verification has two independent parts — the **release signature** over the runtime (manifest + artifact hashes) and the **offline license** (a signed JWT with claims). `telys runtime verify` runs both. A failure surfaces as a `VerificationError` or a license claim error; this page maps each to its cause and fix.

{% hint style="warning" %}
Don't work around a verification failure by disabling checks. A mismatch means the on-disk runtime doesn't match what was signed, or the license doesn't authorize this product. Re-install or re-license instead of overriding trust.
{% endhint %}

## Quick check

```bash
telys runtime verify    # runs signature + license verification, prints what failed
```

The `telys.verify` API checks pieces yourself: `verify_manifest`, `verify_artifact`, and `verify_license`. It requires the `cryptography` package (a hard dependency of the SDK).

## Errors and fixes

<details>

<summary><code>VerificationError</code> — manifest signature invalid</summary>

The signed manifest describes the runtime; its signature is checked with the embedded release public key (RS256, PKCS1v15 + SHA-256).

**Cause:** `telys_manifest.json` or its `telys_manifest.sig` is corrupt, truncated, or was produced with a different signing key.

**Fix:** re-install so the manifest and signature are fetched fresh together, then verify.

```bash
telys runtime install       # or: telys runtime install --file ./bundle
telys runtime verify
```

If you deliberately run a runtime signed by your own release key, point Telys at that key — see "Trusted key overrides" below.

</details>

<details>

<summary><code>VerificationError</code> — artifact hash mismatch</summary>

Each artifact (for example `libty_runtime`, `libame_kernel`) is verified against the SHA-256 recorded in the signed manifest, using a constant-time comparison.

**Cause:** an artifact on disk was modified, partially downloaded, or replaced — its hash no longer matches the manifest.

**Fix:** re-install to restore the exact signed artifacts. Never patch a binary in place.

```bash
telys runtime install
telys runtime verify        # expect a clean pass
```

</details>

<details>

<summary>License rejected — <code>iss</code> / <code>aud</code> / <code>exp</code> / <code>ver</code></summary>

The offline license check is strict: it pins `alg` to RS256, rejects unknown critical headers, and validates the issuer, audience, version, and expiry (with a small grace window), then reads the `products.telys` tier and features.

**Cause and fix**, by claim:

* **`iss` (issuer)** — the issuer isn't the expected one. Default: `https://license.algenta.ai`. For a custom issuer, set `$TELYS_LICENSE_ISSUER`.
* **`aud` (audience)** — the audience isn't accepted. Default: `telys-runtime,algenta-runtime`; override with `$TELYS_LICENSE_AUDIENCE` (comma-separated).
* **`ver` (version)** — only license version `2` is supported. Any other is rejected; obtain a current license via `telys login`.
* **`exp` (expiry)** — the token aged past its expiry plus grace. Sign in again to re-issue, and check your system clock.

```bash
telys login             # refreshes the license to a current, ver:2 token
telys runtime verify
```

</details>

<details>

<summary>Trusted key overrides (custom release or license keys)</summary>

The wheel ships embedded PEM keys: `telys/_keys/telys_release_pub.pem` (runtime signature) and `telys/_keys/telys_license_pub.pem` (license). Override them for an enterprise or self-signed pipeline.

**Cause:** you sign runtimes or licenses with your own keys and need Telys to trust them.

**Fix:** point Telys at your public keys and expected claims via environment variables.

```bash
# Release-signature key (verifies the runtime manifest):
export TELYS_RELEASE_PUBKEY_FILE=/opt/telys/keys/release_pub.pem
# or inline PEM: export TELYS_RELEASE_PUBKEY="-----BEGIN PUBLIC KEY----- ..."

# License key + expected claims:
export TELYS_LICENSE_PUBKEY_FILE=/opt/telys/keys/license_pub.pem
export TELYS_LICENSE_ISSUER=https://license.example.com
export TELYS_LICENSE_AUDIENCE=telys-runtime,algenta-runtime

telys runtime verify
```

You can also verify programmatically with pinned keys:

```python
from telys.verify import verify_license
from datetime import datetime, timezone

claims = verify_license(
    token,                       # the JWT string
    now=int(datetime.now(timezone.utc).timestamp()),  # verify_license wants a Unix int
    product="telys",
)
print(claims["products"]["telys"])   # tier + features
```

Override keys only when you control the signing pipeline; otherwise leave the embedded keys in place.

</details>

## Next steps

If verification points at the license itself rather than the runtime signature, fix it at the sign-in / plan layer.

<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>License &#x26; login issues</strong></td><td>Refresh an expired license, switch plans, sign in headless.</td><td><a href="/pages/f5D2AxbBcG8bokGMGJNZ">/pages/f5D2AxbBcG8bokGMGJNZ</a></td></tr><tr><td><strong>Verify the runtime signature</strong></td><td>The trust model and the full verification walkthrough.</td><td><a href="/pages/as3JvHboA5RxokqNHpAw">/pages/as3JvHboA5RxokqNHpAw</a></td></tr></tbody></table>

Next: [License & login issues](/troubleshooting/license-and-login.md)


---

# 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/troubleshooting/signature-verification.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.
