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

> ## Agent Instructions
> The OpenAPI document at /api-reference/openapi.yaml defines the target contract. Its x-reflections-availability field and each operation's availability notice identify supported test and live forms. Do not infer implementation from a schema or code sample. Live keys support account details, reads of the licenses the calling account holds as licensee or issued as talent (GET /v1/licenses?role=issuer), and GET /v1/generations?license=… for the state of outputs under such a license (summaries only: no prompt, reference, bytes or metadata). Live image checks, submissions and receipts are built but not activated: until activation, a live POST /v1/checks or /v1/generations returns 403 live_not_activated, which must not be retried. Discovery and JWKS are at the origin root (https://app.reflections.ai/.well-known/...), not under /v1.
> Three rules hold everywhere: a decision is never an error (deny and escalate are 200 responses, and a live check still evaluating is a 202 with status checking); generate nothing for a named talent without an allow; deliver nothing until the generation is allow.
> The sandbox accepts personal rk_test_ keys. Persist a separate Idempotency-Key and body for each logical /v1 POST; retry an unknown outcome with the same key and body. OAuth and Talent API MCP remain planned.

# Security

> The threat model of the Talent License Protocol and the security requirements on each role.

This page specifies the threats the Talent License Protocol is designed against, and the security
requirements each role meets in addition to those on the other pages.

## Assets

The protocol protects three things: a talent's consent, as signed licenses and a posture; the
integrity of decisions, tokens and receipts; and the personal data that passes through checks.

## Threat model

| Threat | Example | Answered by |
| - | - | - |
| Generating without a decision | A platform calls the model before the check returns | [TLP-DEC-4](/standard/decision-semantics#at-the-check), [TLP-DEC-32](/standard/decision-semantics#when-the-license-server-cannot-answer) |
| Checking one request and running another | The user's prompt is checked, the rewritten prompt is run | [TLP-DEC-26](/standard/decision-semantics#binding), [TLP-DEC-27](/standard/decision-semantics#binding) |
| Running more than was allowed | One token reused for hundreds of images | `max_generations`, [TLP-TOK-6](/standard/tokens#verifying-a-token), [TLP-TOK-7](/standard/tokens#verifying-a-token) |
| A token used by someone else | A token leaked to another platform or tool | `aud`, short `exp`, TLP-SEC-4 |
| Substituting a model | An allowed request run on a different model | `tlp.execution.model`, [TLP-TOK-6](/standard/tokens#verifying-a-token) |
| Forging a token or receipt | A token signed with a key from its own header | [TLP-TOK-1](/standard/tokens#common-format), TLP-SEC-3 |
| Unrelated bytes on a valid check | A different output submitted under an allowed check | [TLP-DEC-28](/standard/decision-semantics#binding) |
| Moving a receipt to other content | A real receipt copied into an unlicensed file | `artifact_sha256`, [TLP-RCP-5](/standard/receipts#verifying-a-receipt) |
| Spoofed events | A forged `revocation.created` or `generation.released` | TLP-SEC-6, TLP-SEC-7 |
| Missing a revocation | A dropped webhook | [TLP-RVK-7](/standard/revocation#what-a-conformant-platform-does) |
| Treating an outage as permission | The license server times out and the platform generates | [TLP-DEC-2](/standard/decision-semantics#the-three-decisions), [TLP-DEC-32](/standard/decision-semantics#when-the-license-server-cannot-answer) |
| Signing key compromise | A stolen private key | [TLP-RCP-9](/standard/receipts#signing-keys-and-rotation) |
| Downgrade by unknown terms | A new obligation ignored by an old platform | [TLP-OBL-2](/standard/obligations-registry#rules-for-every-obligation) |
| Harvesting personal data | Reading prompts or end users from receipts | [TLP-RCP-3](/standard/receipts#jws-form), [Privacy](/standard/privacy) |

The protocol does not defend against a platform that lies in its checks and also runs its own
model with no generation tool to verify tokens. It narrows that case: outputs carry no valid
receipt, and every attestation a platform makes is on the record.

## Transport and credentials

**TLP-SEC-1.** Every TLP endpoint MUST be served over HTTPS with TLS 1.2 or later, and every party
MUST validate the server's certificate.

**TLP-SEC-2.** A license server MUST authenticate every platform call except receipt reads,
verifications and the discovery document, which are public. A platform MUST keep its credentials
for the license server on its servers and MUST NOT send them to clients or generation tools.

## Tokens and keys

**TLP-SEC-3.** A verifier and a generation tool MUST take keys only from the JWK Set of an issuer
they trust, reached through that issuer's discovery document over HTTPS. They MUST NOT accept
`alg` values other than `ES256`, including `none`.

**TLP-SEC-4.** A platform MAY pass an authorization token to a generation tool and a session token
to its own client, and MUST NOT pass either to anyone else. A platform that serves more than one
licensee MUST give a generation tool only tokens for the request it is running.

**TLP-SEC-5.** Every party that checks `exp`, `iat` or a webhook timestamp MUST keep its clock
synchronized with a time source, and MUST NOT allow more than 60 seconds of leeway on tokens.

## Events

**TLP-SEC-6.** A license server MUST sign every event it delivers as the Standard Webhooks
specification defines: `webhook-id`, `webhook-timestamp` and `webhook-signature` headers, with
HMAC-SHA256 under a per-endpoint secret over `${webhook-id}.${webhook-timestamp}.${body}`, sent
as one or more `v1,<base64>` entries.

**TLP-SEC-7.** A platform MUST verify the signature of every event before acting on it, MUST reject
an event whose timestamp is more than 5 minutes from its clock, and MUST compare signatures in
constant time.

**TLP-SEC-8.** A license server delivers events at least once and in no guaranteed order. A
platform MUST process each event ID once, and MUST ignore an event whose `sequence` is lower than
one it has processed for the same object. Before acting on an event that permits something, such
as `generation.released` or `check.resolved` with `allow`, a platform SHOULD read the object from
the license server.

## Availability

**TLP-SEC-9.** A license server MUST publish availability and latency targets for its check,
generation and session endpoints, and a status page. Because platforms fail closed for named
talent ([TLP-DEC-32](/standard/decision-semantics#when-the-license-server-cannot-answer)), its
availability bounds theirs. The Talent API's target for checks is 99.95% per month.

**TLP-SEC-10.** A license server MAY rate-limit requests. It MUST answer a limited request with
HTTP 429 and a `Retry-After` header, and a platform MUST wait at least that long before retrying.

## Disclosure of vulnerabilities

**TLP-SEC-11.** A license server MUST publish a way to report vulnerabilities and MUST state how it
notifies platforms and verifiers of a key compromise.

## Related

<Columns cols={2}>
  <Card title="Production security" icon="shield-check" href="/production/security">
    Key handling, token verification and webhook signing in the Talent API.
  </Card>

  <Card title="Webhooks" icon="webhook" href="/api-reference/webhooks/overview">
    Signing, retries, ordering and replay.
  </Card>

  <Card title="Tokens" icon="key" href="/standard/tokens">
    The verification algorithm.
  </Card>

  <Card title="Privacy" icon="user-shield" href="/standard/privacy">
    Data minimization on both sides.
  </Card>
</Columns>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.