> ## Documentation Index
> Fetch the complete documentation index at: https://trench-446767c3.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Security Requirements

> Non-negotiable security requirements for Trench Partner API integrations: API key handling, PKCE and state verification, token storage, and refresh discipline.

This page collects the practices we consider necessary for a production Partner API integration. Getting any of them wrong can expose user funds or result in your client being suspended, so we recommend reading it before you go live.

## Secrets

* **Keep your API key server-side.** It is only ever used in calls to `POST /oauth/token` and `POST /oauth/revoke` from your backend, and never belongs on a Partner API request.
* **Give each environment its own key**, so revoking one does not disturb the others.
* **Encrypt tokens at rest** and treat them with the same care as passwords.
* **Never log tokens or keys**, including in error reports and crash traces.

<Warning>
  A leaked API key stays usable until you revoke it, and revoking it disconnects every user who connected through that key. That trade-off is deliberate, since it is what makes revocation immediate rather than leaving the key useful for the remainder of a 60-day refresh lifetime. Plan for the reconnect rather than delaying the revocation.
</Warning>

## Authorization Flow

* **Send and verify `state` on every authorization.** Generate it randomly, store it, and compare it when the user returns. This is your CSRF protection.
* **Use a fresh PKCE verifier for each authorization.** The verifier stays local, and only its SHA-256 hash goes in the URL.
* **Verify `event.origin`** on the `postMessage` from your callback before trusting anything it contains.

```javascript theme={null}
window.addEventListener("message", (event) => {
  if (event.origin !== window.location.origin) return;
  if (event.data?.type !== "trench:oauth") return;
  if (event.data.state !== sessionStorage.getItem("trench_state")) return;
  // safe to use event.data.code
}, { once: true });
```

## Token Handling

* **Handle a `401` by refreshing once**, then re-authorizing if the refresh also fails. Avoid retrying in a loop.
* **Never refresh concurrently for the same user.** Rotation invalidates the loser's token, and replaying it revokes the whole connection.
* **Persist both values on every refresh.** The old refresh token stops working as soon as a new one is issued.
* **Revoke the refresh token to disconnect a user.** Revoking the access token alone only forces an early refresh.

<Warning>
  Refreshing does not invalidate the old access token, which remains valid until its 30-minute expiry. To cut off a leaked access token immediately, revoke it explicitly.
</Warning>

## Trading

* **Avoid sending `"0"` for `minTokensOut` or `minSolOut` in production**, since it accepts any fill price the venue offers at execution time. Sending `slippageBps` instead lets Trench derive the bound for you.
* **Treat `submitted` and `processed` as pending.** Confirm the signature against Solana through your own RPC before telling a user that anything has landed.
* **Do not retry writes automatically.** The API does not support idempotency keys, so a resent request after a timeout can execute twice. Reconcile against the chain instead.

## Environments

Trench does not provide a sandbox. A client in `development` status trades real SOL on mainnet against real liquidity, and the only behaviour the status changes is whether `http://localhost` redirect URIs are accepted.

<Warning>
  Because nothing about a development client is simulated, we recommend testing with wallets you control and amounts you are comfortable losing.
</Warning>

## Revocation

Users can disconnect your application at any time from their Trench settings, Trench can suspend an app, and revoking one of your own API keys disconnects every user who connected through it. All three take effect on the next request and surface as `401 invalid_token`.

Since a connection can disappear without warning, we recommend surfacing this as a reconnect prompt rather than an error page.
